- ?、寫在前?
- ?、Redisson 實作 Redis 分布式鎖的底層原理
(1)加鎖機制
(2)鎖互斥機制
(3)watch dog ?動延期機制
(4)可重?加鎖機制
(5)鎖釋放機制
(6)此種?案 Redis 分布式鎖的缺陷
?、寫在前面
現在?試,?般都會聊聊分布式系統這塊的東?,通常?試官都會從服務框架(Spring Cloud、Dubbo)聊起,?路聊到分布式事務、分布式鎖、ZooKeeper 等知識,
所以咱們這篇?章就來聊聊分布式鎖這塊知識,具體的來看看 Redis 分布式鎖的實作原理,
說實話,如果在公司?落地?產環境?分布式鎖的時候,?定是會?開源類別庫的,?如 Redis分布式鎖,?般就是? Redisson 框架就好了,?常的簡便易?,
?家如果有興趣,可以去看看 Redisson 的官?,看看如何在項?中引? Redisson 的依賴,然后基于 Redis 實作分布式鎖的加鎖與釋放鎖,
下?給?家看?段簡單的使?代碼?段,先直觀的感受?下:
```java
RLock rlock = redission.getLock("mylock");
rlock.lock();
rlock.unlock();
怎么樣,上?那段代碼,是不是感覺簡單的不?!
此外,?家還?持 redis 單實體、redis 哨兵、redis cluster、redis master-slave 等各種部署架構,都可以給你完美實作,
?、Redisson 實作 Redis 分布式鎖的底層原理

- (1)加鎖機制
咱們來看上?那張圖,現在某個客戶端要加鎖,如果該客戶端?對的是?個 redis cluster 集群,他?先會根據 hash 節點選擇?臺機器,
這?注意,僅僅只是選擇?臺機器!這點很關鍵!
緊接著,就會發送?段 lua 腳本到 redis 上
為啥要? lua 腳本呢?
因為??坨復雜的業務邏輯,可以通過封裝在 lua 腳本中發送給 redis,保證這段復雜業務邏輯?的原?性,
那么,這段 lua 腳本是什么意思呢?
KEYS[1] 代表的是你加鎖的那個 key,?如說:
RLock lock = redisson.getLock(“myLock”);
這?你??設定了加鎖的那個鎖 key 就是 “myLock”,
ARGV[1] 代表的就是鎖 key 的默認?存時間,默認 30 秒,
ARGV[2] 代表的是加鎖的客戶端的 ID,類似于下?這樣:
8743c9c0-0795-4907-87fd-6c719a6b4586:1
給?家解釋?下,第?段 if 判斷陳述句,就是? “exists myLock” 命令判斷?下,如果你要加鎖的那個鎖 key 不存在的話,你就進?加鎖,
如何加鎖呢?很簡單,?下?的命令:
hset myLock 8743c9c0-0795-4907-87fd-6c719a6b4586:1 1
上述就代表 “8743c9c0-0795-4907-87fd-6c719a6b4586:1” 這個客戶端對 “myLock” 這個鎖key 完成了加鎖,
接著會執? “pexpire myLock 30000” 命令,設定 myLock 這個鎖 key 的?存時間是 30 秒
-
(2)鎖互斥機制
那么在這個時候,如果客戶端 2 來嘗試加鎖,執?了同樣的?段 lua 腳本,會咋樣呢?
很簡單,第?個 if 判斷會執? “exists myLock” ,發現 myLock 這個鎖 key 已經存在了,
接著第?個 if 判斷,判斷?下,myLock 鎖 key 的 hash 資料結構中,是否包含客戶端 2 的 ID,
但是明顯不是的,因為那?包含的是客戶端 1 的 ID,
所以,客戶端 2 會獲取到 pttl myLock 回傳的?個數字,這個數字代表了 myLock 這個鎖
key 的剩余?存時間,?如還剩 15000 毫秒的?存時間,
此時客戶端 2 會進??個 while 回圈,不停的嘗試加鎖, -
(3)watch dog ?動延期機制
客戶端 1 加鎖的鎖 key 默認?存時間才 30 秒,如果超過了 30 秒,客戶端 1 還想?直持有這把鎖,怎么辦呢?
簡單!只要客戶端 1 ?旦加鎖成功,就會啟動?個 watch dog 看?狗,他是?個后臺執行緒,會每隔 10 秒檢查?下,如果客戶端 1 還持有鎖 key,那么就會不斷的延?鎖 key 的?存時間,
(4)可重?加鎖機制
那如果客戶端 1 都已經持有了這把鎖了,結果可重?的加鎖會怎么樣呢?
第?個 if 判斷肯定不成?, “exists myLock” 會顯示鎖 key 已經存在了,
第?個 if 判斷會成?,因為 myLock 的 hash 資料結構中包含的那個 ID,就是客戶端 1 的那個ID,也就是 “8743c9c0-0795-4907-87fd-6c719a6b4586:1”此時就會執?可重?加鎖的邏輯,他會?:incrby myLock 8743c9c0-0795-4907-87fd-6c71a6b4586:1 1通過這個命令,對客戶端 1 的加鎖次數,累加 1,
-
(5)鎖釋放機制
如果執? lock.unlock() ,就可以釋放分布式鎖,此時的業務邏輯也是?常簡單的,
其實說?了,就是每次都對 myLock 資料結構中的那個加鎖次數減 1,
如果發現加鎖次數是 0 了,說明這個客戶端已經不再持有鎖了,此時就會?:
“del myLock” 命令,從 redis ?洗掉這個 key,
然后呢,另外的客戶端 2 就可以嘗試完成加鎖了,
這就是所謂的分布式鎖的開源 Redisson 框架的實作機制,
?般我們在?產系統中,可以? Redisson 框架提供的這個類別庫來基于 redis 進?分布式鎖的加鎖與釋放鎖, -
(6)此種?案 Redis 分布式鎖的缺陷
其實上?那種?案最?的問題,就是如果你對某個 redis master 實體,寫?了 myLock 這種鎖key 的 value,此時會異步復制給對應的 master slave 實體,
但是這個程序中?旦發? redis master 宕機,主備切換,redis slave 變為了 redis master,
接著就會導致,客戶端 2 來嘗試加鎖的時候,在新的 redis master 上完成了加鎖,?客戶端 1也以為??成功加了鎖,
此時就會導致多個客戶端對?個分布式鎖完成了加鎖,
這時系統在業務語意上?定會出現問題,導致各種臟資料的產?,
所以這個就是 redis cluster,或者是 redis master-slave 架構的主從異步復制導致的 redis 分布式
鎖的最?缺陷:在 redis master 實體宕機的時候,可能導致多個客戶端同時完成加鎖,
下一篇我們聊聊 zookeeper實作分布式鎖
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/277498.html
標籤:其他
下一篇:Web應用白屏時間優化
