Zookeeper 如何實現分佈式鎖

什麼是臨時順序節點?

在這裏插入圖片描述

Zookeeper 的數據存儲結構就像一棵樹,這棵樹由節點組成,這種節點叫做 Znode。
Znode 分爲四種類型:

持久節點(PERSISTENT)

默認的節點類型。創建節點的客戶端與 Zookeeper 斷開連接後,該節點依舊存在。

持久節點順序節點(PERSISTENT_SEQUENTIAL)

所謂順序節點,就是在創建節點時,Zookeeper 根據創建的時間順序給該節點名稱進行編號:
在這裏插入圖片描述

臨時節點(EPHEMERAL)

和持久節點相反,當創建節點的客戶端與 Zookeeper 斷開連接後,臨時節點會被刪除:
在這裏插入圖片描述

臨時順序節點(EPHEMERAL_SEQUENTIAL)

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

Zookeeper 分佈式鎖的原理

Zookeeper 分佈式鎖恰恰應用了臨時順序節點。具體如何實現呢?讓我們來看一看詳細步驟:

獲取鎖

首先,在 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 同樣搶鎖失敗,進入了等待狀態。

在這裏插入圖片描述
這樣一來,Client1 得到了鎖,Client2 監聽了 Lock1,Client3 監聽了 Lock2。這恰恰形成了一個等待隊列.

釋放鎖

釋放鎖分爲兩種情況:

任務完成,客戶端顯示釋放

當任務完成時,Client1 會顯示調用刪除節點 Lock1 的指令。
在這裏插入圖片描述

任務執行過程中,客戶端崩潰

獲得鎖的 Client1 在任務執行過程中,如果崩潰,則會斷開與 Zookeeper 服務端的鏈接。根據臨時節點的特性,相關聯的節點 Lock1 會隨之自動刪除。

由於 Client2 一直監聽着 Lock1 的存在狀態,當 Lock1 節點被刪除,Client2 會立刻收到通知。這時候 Client2 會再次查詢 ParentLock 下面的所有節點,確認自己創建的節點 Lock2 是不是目前最小的節點。如果是最小,則 Client2 順理成章獲得了鎖。

同理,如果 Client2 也因爲任務完成或者節點崩潰而刪除了節點 Lock2,那麼 Client3 就會接到通知。

最終,Client3 成功得到了鎖。

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