目錄node
標籤 : Zookeeper 分佈式redis
加鎖, 解鎖, 鎖超時數據庫
- 要保證原子性操做, 加鎖和鎖超時的操做要一次性執行完畢
- 防止誤刪鎖
- 在誤刪的基礎上, 加一個守護線程, 爲鎖續命.
Zookeeper的數據存儲結構就像是一棵樹, 這棵樹由節點組成, 這種節點叫作Znode. Znode分爲四種類型.服務器
默認的節點類型, 建立節點的客戶端和Zookeeper斷開鏈接以後, 該節點依舊存在.框架
所謂順序節點, 就是在建立節點的時候, Zookeeper根據節點的建立時間順序給節點的名稱進行編號.分佈式
和持久節點相反, 當建立節點的客戶端與Zookeeper斷開鏈接以後,臨時節點會被刪除.性能
在建立節點時, Zookeeper根據建立的時間順序給該節點名稱進行編號; 當建立節點的客戶端與Zookeeper斷開鏈接以後,臨時節點會被刪除.線程
上面已經說了Znode的四種類型, 其中最後一種類型 臨時順序節點 是最有利於實現Zookeeper分佈式鎖的.3d
- 首先, 在Zookeeper當中建立一個持久節點ParentLock. 當第一個客戶端想要得到操做某項數據的鎖的時候,須要在該持久節點之下簡歷一個臨時順序節點
Lock1
.
- 以後,
客戶端1
查找ParentLock
下面全部的臨時順序節點並按照大小排序, 判斷本身所建立的節點Lock1
是否是順序最靠前的一個. 若是是第一個節點,則成功得到鎖.
- 此時,
客戶端2
前來獲取該項數據的鎖, 則在ParentLock
下再建立一個臨時順序節點Lock2
.
客戶端2
查找ParentLock下面全部的臨時順序節點並排序,發現本身的Lock2
節點並非最靠前的. 因而客戶端2
向排序僅僅比它靠前的Lock1
註冊Watcher
, 用於監聽Lock1
動態. 這意味着Lock2
搶鎖失敗, 進入等待狀態.
- 此時, 若是有一個
客戶端3
前來獲取鎖, 則在ParentLock
下在建立一個臨時順序節點Lock3
.
客戶端3
查找ParentLock
下面全部的臨時順序節點並排序, 判斷本身所建立的節點Lock3
是否是順序最靠前的一個, 結果發現Lock3
不是最靠前的. 因而客戶端3
一樣搶鎖失敗, 進入了等待狀態.
- 這個時候
客戶端1
獲得了鎖,客戶端2
監聽了客戶端1
,客戶端3
監聽了客戶端2
. 這樣恰好造成一個等待的隊列.
釋放鎖有兩種狀況code
- 當任務完成時,
客戶端1
會顯示的調用刪除節點Lock1
的指令.
- 得到鎖的
客戶端1
在執行任務的過程當中, 若是崩潰, 則會斷開和Zookeeper
服務器的連接, 根據臨時節點的特性, 相關聯的Lock1
會隨之自動刪除.
- 因爲
客戶端2
一直在監聽Lock1
的狀態,這個時候發現Lock1
註銷了,客戶端2
會當即接收到通知. 這個時候客戶端2
會再次查詢ParentLock
下的全部節點, 確認本身所建立的節點是否是最小的節點, 若是是最小的則成功得到鎖.
同理可推至
客戶端3
分佈式鎖 | 優勢 | 缺點 |
---|---|---|
Zookeeper | 1.有封裝好的框架,容易實現. 2.有等待鎖的機制( Watcher ),能夠提升搶鎖的效率,好處多多 |
添加和刪除節點的性能比較低 |
Redis | Set 和Del 的性能比較高(畢竟鍵值數據庫,Hash) |
1.實現複雜,須要考慮原子性,誤刪等狀況.2.沒有等待鎖的機制,只能經過客戶端的自旋來等鎖,效率低下. |