如何使用zookeepe實現分佈式鎖--抄自小灰

在這裏插入圖片描述
1、zookeeper的四種節點類型:
a、持久節點:默認的節點類型,創建節點的客戶端和zookeeper斷開連接後,該節點依舊存在。

b、持久節點順序節點:
在創建節點時,zookeeper根據創建的時間順序給節點名稱進行編號。如下所示:
在這裏插入圖片描述
c、臨時節點
和持久節點相反,當創建節點的客戶端與zookeeper斷開連接後,臨時節點會被刪除。

d、臨時順序節點
臨時順序節點,結合了臨時節點和順序節點的特點:在創建節點時,zookeeper根據創建的時間順序和該節點名稱進行編號。當創建節點的客戶端與zookeeper斷開連接後,臨時節點會被刪除。

2、zookeeper分佈式鎖的原理
zookeeper分佈式鎖恰恰應用了臨時順序節點。如何實現呢?
a、獲取鎖
首先,在Zookeeper當中創建一個持久節點ParentLock,當第一個客戶端想要獲得鎖時,需要在ParentLock這個節點下面創建一個臨時順序節點lock1。
在這裏插入圖片描述
之後,client1查找ParentLock下面所有的臨時順序節點並排序,判斷自己所創建的節點lock1是不是順序最靠前的一個,如果是第一個節點,則成功獲得鎖。
在這裏插入圖片描述
此時,如果有一個客戶端client2前來獲取鎖,則在parentlock下再創建一個臨時順序節點lock2
在這裏插入圖片描述
client2查找parentlock下面所有的臨時順序節點並排序,判斷自己所創建的節點lock2是不是順序最靠前的一個,結果發現節點lock2並不是最小的。於是client2向排序僅比它靠前的節點lock1註冊watcher,用於監聽lock1節點是否存在。此時意味着client2搶鎖失敗,進入了等待狀態。
在這裏插入圖片描述
此時,如果又有一個客戶端client3前來獲取鎖,則在parentLock下再創建一個臨時順序節點lock3.
在這裏插入圖片描述
Client3查找parentLock下面所有的臨時順序節點並排序,判斷自己所創建的節點lock3是不是順序最靠前的一個,結果同樣發現節點lock3並不是最小的。於是client3向排序僅比它靠前的節點lock2註冊watcher,用於監聽lock2節點是否存在。這同樣意味着client3同樣搶鎖失敗。並進入等待狀態。
在這裏插入圖片描述
這就很有意思了,首次搶到鎖的客戶端獲取到鎖以後,由於每次來的客戶端都會進行排序,也就是每個客戶端都會生成一個watch來監聽前一個是否釋放了鎖。(但是如果我希望每個客戶端都需要有一個獲取鎖的超時時間呢?由於是臨時節點,可以認爲會自動釋放,那是否也就意味着zookeeper中需要有一個自動更新watch的功能?)

b、釋放鎖
釋放鎖分爲兩種情況。
第一種情況:任務完成,客戶端顯示釋放鎖
當任務完成後,client1會顯示調用刪除節點Lock1的指令。而這個節點被刪除後,會被watch監聽到,然後後面的客戶端就可以去獲取到鎖了。
在這裏插入圖片描述

第二種情況:任務執行過程中,客戶端崩潰
獲得鎖的client在任務執行過程中,如果崩潰調了,就會斷開與zookeeper服務端的鏈接。根據臨時節點的特性,相關聯的節點lock1會隨之自動刪除。
在這裏插入圖片描述
由於client2一直監聽着lock1的存在狀態,當Lock1節點被刪除,client2會立刻收到通知,這時候client2會再次查詢ParentLock下面的所有節點,確認自己創建的節點lock2是不是目前最小的節點,如果是最小,那麼就獲取到鎖。

3、redis分佈式鎖和zookeeper分佈式鎖的優缺點比較:
在這裏插入圖片描述
實際工作中,我選擇使用的是redis來實現分佈式鎖,之所以不使用zookeeper主要是由於需要引入這個zk框架,依賴相對而言變多了,而redis是當前我們就使用的工具,所以選用了redis。不過大傢俱體選擇的時候還是要根據實際情況來分析。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章