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