您好,登錄后才能下訂單哦!
這期內容當中小編將會給大家帶來有關如何進行Zookeeper 分布式鎖的分析,文章內容豐富且以專業的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。
我們借助 Zookeeper 實現一個不可重入的分布式鎖!
分布式鎖對 Java 的 JUC 包來說就顯得無能為力了。所以我們要借助 Zookeeper 的最小版本,Redis 的 set 函數,數據庫鎖來實現分布式鎖。
我們知道在 Zookeeper 中是使用文件目錄的格式存放節點內容,其中節點類型分為:
持久節點(PERSISTENT ):節點創建后,一直存在,直到主動刪除了該節點。
臨時節點(EPHEMERAL):生命周期和客戶端會話綁定,一旦客戶端會話失效,這個節點就會自動刪除。
序列節點(SEQUENTIAL ):多個線程創建同一個順序節點時候,每個線程會得到一個帶有編號的節點,節點編號是遞增不重復的,如下圖:
如上圖,三個線程分別創建路徑為 /root/node 的節點,可知在 zk 服務器端會在 root 下存在三個 node 節點,并且線程編號是唯一遞增。
具體在節點創建過程中,可以混合使用,比如臨時順序節點(EPHEMERAL_SEQUENTIAL),本文我們就使用臨時順序節點來實現分布式鎖。
創建臨時順序節點,比如 /root/node,假設返回結果為 nodeId。
獲取 /root 下所有孩子節點,用自己創建的 nodeId 的序號與所有子節點比較,看看自己是不是編號最小的。如果是最小的則就相當于獲取到了鎖,如果自己不是最小的,則從所有子節點里面獲取比自己次小的一個節點,然后設置監聽該節點的事件,然后掛起當前線程。
當最小編號的線程獲取鎖,處理完業務后刪除自己對應的 nodeId,刪除后會激活比自己大一號的節點的線程從阻塞變為運行態,被激活的線程應該就是當前 node 序列號最小的了,然后就會獲取到鎖。
明白原理后,代碼寫起來就非常的簡單了。
ZookeeperDistributedLock 的構造函數創建 zkclient,并且注冊了監聽事件,然后調用 connectedSignal.await() 掛起當前線程。當 zkclient 鏈接到服務器后,會給監聽器發送 SyncConnected 事件,監聽器判斷當前鏈接已經建立了,則調用 connectedSignal.countDown(); 激活當前線程,然后創建 root 節點。
獲取鎖的方法 lock,內部首先創建 /root/lockName 的順序臨時節點,然后獲取 /root 下所有的孩子節點,并對子節點進行排序,然后判斷自己是不是最小的編號,如果是直接返回 true 標示獲取鎖成功。否者看比自己小一個號的節點是否存在,存在則注冊該節點的事件,然后掛起當前線程,等待比自己小一個數的節點釋放鎖后發送節點刪除事件,事件里面激活當前線程。
釋放鎖的方法 unlock 比較簡單,就是簡單的刪除獲取鎖時候創建的節點。
Zookeeper 非常的強大,當你真正的了解后,你會發現它能做很多事情。
光分布鎖方面,它都能幫助我們實現好幾種,如下面我列舉的這些:
可重入鎖Shared Reentrant Lock
不可重入鎖Shared Lock
可重入讀寫鎖Shared Reentrant Read Write Lock
信號量Shared Semaphore
多鎖對象 Multi Shared Lock
上述就是小編為大家分享的如何進行Zookeeper 分布式鎖的分析了,如果剛好有類似的疑惑,不妨參照上述分析進行理解。如果想知道更多相關知識,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。