zookeeper分布式锁的原理
2019獨角獸企業重金招聘Python工程師標準>>>
lock操作過程:
首先為一個lock場景,在zookeeper中指定對應的一個根節點,用于記錄資源競爭的內容
每個lock創建后,會lazy在zookeeper中創建一個node節點,表明對應的資源競爭標識。 (小技巧:node節點為EPHEMERAL_SEQUENTIAL,自增長的臨時節點)
進行lock操作時,獲取對應lock根節點下的所有字節點,也即處于競爭中的資源標識
按照Fair競爭的原則,按照對應的自增內容做排序,取出編號最小的一個節點做為lock的owner,判斷自己的節點id是否就為owner id,如果是則返回,lock成功。
如果自己非owner id,按照排序的結果找到序號比自己前一位的id,關注它鎖釋放的操作(也就是exist watcher),形成一個鏈式的觸發過程。
unlock操作過程:
將自己id對應的節點刪除即可,對應的下一個排隊的節點就可以收到Watcher事件,從而被喚醒得到鎖后退出
其中的幾個關鍵點:
node節點選擇為EPHEMERAL_SEQUENTIAL很重要。
* 自增長的特性,可以方便構建一個基于Fair特性的鎖,前一個節點喚醒后一個節點,形成一個鏈式的觸發過程。可以有效的避免"驚群效應"(一個鎖釋放,所有等待的線程都被喚醒),有針對性的喚醒,提升性能。
* 選擇一個EPHEMERAL臨時節點的特性。因為和zookeeper交互是一個網絡操作,不可控因素過多,比如網絡斷了,上一個節點釋放鎖的操作會失敗。臨時節點是和對應的session掛接的,session一旦超時或者異常退出其節點就會消失,類似于ReentrantLock中等待隊列Thread的被中斷處理。
獲取lock操作是一個阻塞的操作,而對應的Watcher是一個異步事件,所以需要使用信號進行通知,正好使用上一篇文章中提到的BooleanMutex,可以比較方便的解決鎖重入的問題。(鎖重入可以理解為多次讀操作,鎖釋放為寫搶占操作)
注意:
使用EPHEMERAL會引出一個風險:在非正常情況下,網絡延遲比較大會出現session timeout,zookeeper就會認為該client已關閉,從而銷毀其id標示,競爭資源的下一個id就可以獲取鎖。這時可能會有兩個process同時拿到鎖在跑任務,所以設置好session timeout很重要。
同樣使用PERSISTENT同樣會存在一個死鎖的風險,進程異常退出后,對應的競爭資源id一直沒有刪除,下一個id一直無法獲取到鎖對象。
轉載于:https://my.oschina.net/91jason/blog/500503
總結
以上是生活随笔為你收集整理的zookeeper分布式锁的原理的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 挑战JavaScript正则表达式每日两
- 下一篇: 修改文件访问权限