zookeeper分佈式鎖

zookeeper的節點有四種節點:node


Persist vs. Ephemeral

  • Persist節點,一旦被建立,便不會意外丟失,即便服務器所有重啓也依然存在。每一個 Persist 節點便可包含數據,也可包含子節點
  • Ephemeral節點,在建立它的客戶端與服務器間的 Session 結束時自動被刪除。服務器重啓會致使 Session 結束,所以
    Ephemeral 類型的 znode 此時也會自動刪除

Sequence vs. Non-sequence

  • Non-sequence節點,多個客戶端同時建立同一 Non-sequence節點時,只有一個可建立成功,其它勻失敗。而且建立出的節點名稱與建立時指定的節點名徹底同樣服務器

  • Sequence節點,建立出的節點名在指定的名稱以後帶有10位10進制數的序號。多個客戶端建立同一名稱的節點時,都能建立成功,只是序號不一樣

此外,zookeeper有watch機制,能夠監聽到數據的變化從而觸發watch,watch有如下特色:架構

  • 主動推送  Watch被觸發時,由 Zookeeper 服務器主動將更新推送給客戶端,而不須要客戶端輪詢。分佈式

  • 一次性  數據變化時,Watch 只會被觸發一次。若是客戶端想獲得後續更新的通知,必需要在 Watch 被觸發後從新註冊一個Watch。性能

  • 可見性  若是一個客戶端在讀請求中附帶 Watch,Watch 被觸發的同時再次讀取數據,客戶端在獲得 Watch消息以前確定不可能看到更新後的數據。換句話說,更新通知先於更新結果。spa

  • 順序性  若是多個更新觸發了多個 Watch ,那 Watch 被觸發的順序與更新順序一致。線程

基於zookeeper的分佈式鎖有兩種實現方式:公平模式和非公平模式,能夠利用zookeeper的節點的這幾種特性來實現不一樣的分佈式鎖code

一.非公平模式:

  1. 競爭鎖:進程

    非公平模式的zookeeper的分佈式鎖使用的是Non-sequence+Ephemeral節點實現的,此節點的實現方式和Redis實現分佈式鎖的實現方式比較相似.

    zookeeper因爲Non-sequence節點的特性,在建立節點時,多個節點只會建立一個成功,這個節點就是主節點,其他的節點就是follower,這樣就保證了只有一個線程可以拿到鎖圖片

  2. 釋放鎖:

    因爲Ephemeral節點的存在,鎖的得到者應該可以正確釋放已經得到的鎖,而且當得到鎖的進程宕機時,鎖應該自動釋放,從而使得其它競爭方能夠得到該鎖,從而避免出現死鎖的狀態

    或者leader主動釋放鎖,而且當領導所在進程宕機時,領導權應該自動釋放,從而使得其它參與者可從新競爭領導而避免進入無主狀態

  3. 感知鎖的釋放:

    感知鎖的釋放主要是watch機制的存在,在leader釋放鎖時,節點刪除,其餘線程會感知到鎖的釋放,從而競爭鎖

圖片描述
總結:

非公平模式實現簡單,每一輪選舉方法都徹底同樣
競爭參與方很少的狀況下,效率高。每一個 Follower 經過 Watch 感知到節點被刪除的時間不徹底同樣,只要有一個 Follower 獲得通知即發起競選,便可保證當時有新的 Leader 被選出
給Zookeeper 集羣形成的負載大,所以擴展性差。若是有上萬個客戶端都參與競選,意味着同時會有上萬個寫請求發送給 Zookeper。如《Zookeeper架構》一文所述,Zookeeper 存在單點寫的問題,寫性能不高。同時一旦 Leader 放棄領導權,Zookeeper 須要同時通知上萬個 Follower,負載較大。

二.公平模式:

  1. 競爭鎖:

    公平鎖主要依據的是zookeeper的Sequence+Ephemeral節點的特性實現的
       在線程啓動時會根據線程進行編號,因爲Sequence節點的特性,每一個線程均能成功建立出節點,此處節點的選舉有些相似於zookeeper的選舉,在啓動時會根據節點的編號順序來指定主節點,例若有三個節點,編號分別爲1,2,3,此時會指定最小的節點爲leader,其他的節點爲follower,同時此節點對應的線程watch是比本身節點小的節點,也就是說3線程watch2節點,2線程watch1節點

圖片描述

  1. 釋放鎖:

    Leader 若是主動放棄領導權,直接刪除其建立的節點便可.
       若是 Leader 所在進程意外宕機,其與 Zookeeper 間的 Session 結束,因爲其建立的節點爲Ephemeral類型,故該節點自動被刪除.
  2. 感知鎖的釋放:

    與非公平模式不一樣,每一個 Follower 並不是都 Watch 由 Leader 建立出來的節點,而是 Watch 序號恰好比本身序號小的節點,因此主節點釋放後恰好比主節點序號大的節點就會感知到,好比:1節點釋放後2線程會watch到1節點釋放鎖從而競爭鎖,可是在競爭鎖以前會判斷此節點是不是最小的節點,若是不是仍然不會成爲主節點.(1節點釋放鎖以前2節點宕機的狀況下,3線程會watch到2節點的釋放,此時3線程會判斷3節點是不是最小的節點,因爲此時1節點沒有刪除,因此3節點不會成爲leader,而且3線程會watch比2節點小的節點也就是1節點)

圖片描述
總結:

實現相對複雜
擴展性好,每一個客戶端都只 Watch 一個節點且每次節點被刪除只須通知一個客戶端
舊 Leader 放棄領導權時,其它客戶端根據競選的前後順序(也即節點序號)成爲新 Leader,這也是公平模式的由來
延遲相對非公平模式要高,由於它必須等待特定節點獲得通知才能選出新的 Leader

本文參考自深刻淺出Zookeeper(二) 基於Zookeeper的分佈式鎖與領導選舉

相關文章
相關標籤/搜索