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