ZooKeeper分布式鎖的實(shí)現(xiàn)原理(轉(zhuǎn)載)

文章轉(zhuǎn)載自:https://juejin.im/post/5c01532ef265da61362232ed#comment

一豪墅、寫(xiě)在前面

之前寫(xiě)過(guò)一篇文章(《拜托瓶堕,面試請(qǐng)不要再問(wèn)我Redis分布式鎖的實(shí)現(xiàn)原理》)镜豹,給大家說(shuō)了一下Redisson這個(gè)開(kāi)源框架是如何實(shí)現(xiàn)Redis分布式鎖原理的副瀑,這篇文章再給大家聊一下ZooKeeper實(shí)現(xiàn)分布式鎖的原理。

同理蒸痹,我是直接基于比較常用的Curator這個(gè)開(kāi)源框架憎瘸,聊一下這個(gè)框架對(duì)ZooKeeper(以下簡(jiǎn)稱(chēng)zk)分布式鎖的實(shí)現(xiàn)。

一般除了大公司是自行封裝分布式鎖框架之外谨垃,建議大家用這些開(kāi)源框架封裝好的分布式鎖實(shí)現(xiàn),這是一個(gè)比較快捷省事兒的方式硼控。

二刘陶、ZooKeeper分布式鎖機(jī)制

接下來(lái)我們一起來(lái)看看,多客戶(hù)端獲取及釋放zk分布式鎖的整個(gè)流程及背后的原理牢撼。

首先大家看看下面的圖匙隔,如果現(xiàn)在有兩個(gè)客戶(hù)端一起要爭(zhēng)搶zk上的一把分布式鎖,會(huì)是個(gè)什么場(chǎng)景熏版?

image.png

如果大家對(duì)zk還不太了解的話(huà)纷责,建議先自行百度一下,簡(jiǎn)單了解點(diǎn)基本概念撼短,比如zk有哪些節(jié)點(diǎn)類(lèi)型等等再膳。

參見(jiàn)上圖。zk里有一把鎖曲横,這個(gè)鎖就是zk上的一個(gè)節(jié)點(diǎn)喂柒。然后呢,兩個(gè)客戶(hù)端都要來(lái)獲取這個(gè)鎖禾嫉,具體是怎么來(lái)獲取呢灾杰?

咱們就假設(shè)客戶(hù)端A搶先一步,對(duì)zk發(fā)起了加分布式鎖的請(qǐng)求熙参,這個(gè)加鎖請(qǐng)求是用到了zk中的一個(gè)特殊的概念艳吠,叫做“臨時(shí)順序節(jié)點(diǎn)”。

簡(jiǎn)單來(lái)說(shuō)孽椰,就是直接在"my_lock"這個(gè)鎖節(jié)點(diǎn)下昭娩,創(chuàng)建一個(gè)順序節(jié)點(diǎn)泥兰,這個(gè)順序節(jié)點(diǎn)有zk內(nèi)部自行維護(hù)的一個(gè)節(jié)點(diǎn)序號(hào)。

比如說(shuō)题禀,第一個(gè)客戶(hù)端來(lái)搞一個(gè)順序節(jié)點(diǎn)鞋诗,zk內(nèi)部會(huì)給起個(gè)名字叫做:xxx-000001。然后第二個(gè)客戶(hù)端來(lái)搞一個(gè)順序節(jié)點(diǎn)迈嘹,zk可能會(huì)起個(gè)名字叫做:xxx-000002削彬。大家注意一下,最后一個(gè)數(shù)字都是依次遞增的秀仲,從1開(kāi)始逐次遞增融痛。zk會(huì)維護(hù)這個(gè)順序。

所以這個(gè)時(shí)候神僵,假如說(shuō)客戶(hù)端A先發(fā)起請(qǐng)求雁刷,就會(huì)搞出來(lái)一個(gè)順序節(jié)點(diǎn),大家看下面的圖保礼,Curator框架大概會(huì)弄成如下的樣子:

image.png

大家看沛励,客戶(hù)端A發(fā)起一個(gè)加鎖請(qǐng)求,先會(huì)在你要加鎖的node下搞一個(gè)臨時(shí)順序節(jié)點(diǎn)炮障,這一大坨長(zhǎng)長(zhǎng)的名字都是Curator框架自己生成出來(lái)的目派。

然后,那個(gè)最后一個(gè)數(shù)字是"1"胁赢。大家注意一下企蹭,因?yàn)榭蛻?hù)端A是第一個(gè)發(fā)起請(qǐng)求的,所以給他搞出來(lái)的順序節(jié)點(diǎn)的序號(hào)是"1"智末。

接著客戶(hù)端A創(chuàng)建完一個(gè)順序節(jié)點(diǎn)谅摄。還沒(méi)完,他會(huì)查一下"my_lock"這個(gè)鎖節(jié)點(diǎn)下的所有子節(jié)點(diǎn)系馆,并且這些子節(jié)點(diǎn)是按照序號(hào)排序的送漠,這個(gè)時(shí)候他大概會(huì)拿到這么一個(gè)集合:

image.png

接著客戶(hù)端A會(huì)走一個(gè)關(guān)鍵性的判斷,就是說(shuō):唉它呀!兄弟螺男,這個(gè)集合里棒厘,我創(chuàng)建的那個(gè)順序節(jié)點(diǎn)纵穿,是不是排在第一個(gè)啊奢人?

如果是的話(huà)谓媒,那我就可以加鎖了啊何乎!因?yàn)槊髅魑揖褪堑谝粋€(gè)來(lái)創(chuàng)建順序節(jié)點(diǎn)的人句惯,所以我就是第一個(gè)嘗試加分布式鎖的人巴帘纭!

bingo抢野!加鎖成功拷淘!大家看下面的圖,再來(lái)直觀的感受一下整個(gè)過(guò)程指孤。

image.png

接著假如說(shuō)启涯,客戶(hù)端A都加完鎖了,客戶(hù)端B過(guò)來(lái)想要加鎖了恃轩,這個(gè)時(shí)候他會(huì)干一樣的事兒:先是在"my_lock"這個(gè)鎖節(jié)點(diǎn)下創(chuàng)建一個(gè)臨時(shí)順序節(jié)點(diǎn)结洼,此時(shí)名字會(huì)變成類(lèi)似于:

image.png

大家看看下面的圖:

image.png

客戶(hù)端B因?yàn)槭堑诙€(gè)來(lái)創(chuàng)建順序節(jié)點(diǎn)的,所以zk內(nèi)部會(huì)維護(hù)序號(hào)為"2"叉跛。

接著客戶(hù)端B會(huì)走加鎖判斷邏輯松忍,查詢(xún)"my_lock"鎖節(jié)點(diǎn)下的所有子節(jié)點(diǎn),按序號(hào)順序排列筷厘,此時(shí)他看到的類(lèi)似于:

image.png

同時(shí)檢查自己創(chuàng)建的順序節(jié)點(diǎn)鸣峭,是不是集合中的第一個(gè)?

明顯不是啊酥艳,此時(shí)第一個(gè)是客戶(hù)端A創(chuàng)建的那個(gè)順序節(jié)點(diǎn)叽掘,序號(hào)為"01"的那個(gè)。所以加鎖失敗玖雁!

加鎖失敗了以后更扁,客戶(hù)端B就會(huì)通過(guò)ZK的API對(duì)他的順序節(jié)點(diǎn)的上一個(gè)順序節(jié)點(diǎn)加一個(gè)監(jiān)聽(tīng)器。zk天然就可以實(shí)現(xiàn)對(duì)某個(gè)節(jié)點(diǎn)的監(jiān)聽(tīng)赫冬。

如果大家還不知道zk的基本用法浓镜,可以百度查閱,非常的簡(jiǎn)單劲厌√叛Γ客戶(hù)端B的順序節(jié)點(diǎn)是:

image.png

他的上一個(gè)順序節(jié)點(diǎn),不就是下面這個(gè)嗎补鼻?

image.png

即客戶(hù)端A創(chuàng)建的那個(gè)順序節(jié)點(diǎn)哄啄!

所以,客戶(hù)端B會(huì)對(duì):

image.png

這個(gè)節(jié)點(diǎn)加一個(gè)監(jiān)聽(tīng)器风范,監(jiān)聽(tīng)這個(gè)節(jié)點(diǎn)是否被刪除等變化咨跌!大家看下面的圖。

image.png

接著硼婿,客戶(hù)端A加鎖之后锌半,可能處理了一些代碼邏輯,然后就會(huì)釋放鎖寇漫。那么刊殉,釋放鎖是個(gè)什么過(guò)程呢殉摔?

其實(shí)很簡(jiǎn)單,就是把自己在zk里創(chuàng)建的那個(gè)順序節(jié)點(diǎn)记焊,也就是:

image.png

這個(gè)節(jié)點(diǎn)給刪除逸月。

刪除了那個(gè)節(jié)點(diǎn)之后,zk會(huì)負(fù)責(zé)通知監(jiān)聽(tīng)這個(gè)節(jié)點(diǎn)的監(jiān)聽(tīng)器遍膜,也就是客戶(hù)端B之前加的那個(gè)監(jiān)聽(tīng)器彻采,說(shuō):兄弟,你監(jiān)聽(tīng)的那個(gè)節(jié)點(diǎn)被刪除了捌归,有人釋放了鎖肛响。

image.png

此時(shí)客戶(hù)端B的監(jiān)聽(tīng)器感知到了上一個(gè)順序節(jié)點(diǎn)被刪除,也就是排在他之前的某個(gè)客戶(hù)端釋放了鎖惜索。

此時(shí)特笋,就會(huì)通知客戶(hù)端B重新嘗試去獲取鎖,也就是獲取"my_lock"節(jié)點(diǎn)下的子節(jié)點(diǎn)集合巾兆,此時(shí)為:

image.png

集合里此時(shí)只有客戶(hù)端B創(chuàng)建的唯一的一個(gè)順序節(jié)點(diǎn)了猎物!

然后呢,客戶(hù)端B判斷自己居然是集合中的第一個(gè)順序節(jié)點(diǎn)角塑,bingo蔫磨!可以加鎖了!直接完成加鎖圃伶,運(yùn)行后續(xù)的業(yè)務(wù)代碼即可堤如,運(yùn)行完了之后再次釋放鎖。

image.png

三窒朋、總結(jié)

其實(shí)如果有客戶(hù)端C搀罢、客戶(hù)端D等N個(gè)客戶(hù)端爭(zhēng)搶一個(gè)zk分布式鎖,原理都是類(lèi)似的侥猩。

  • 大家都是上來(lái)直接創(chuàng)建一個(gè)鎖節(jié)點(diǎn)下的一個(gè)接一個(gè)的臨時(shí)順序節(jié)點(diǎn)
  • 如果自己不是第一個(gè)節(jié)點(diǎn)榔至,就對(duì)自己上一個(gè)節(jié)點(diǎn)加監(jiān)聽(tīng)器
  • 只要上一個(gè)節(jié)點(diǎn)釋放鎖,自己就排到前面去了欺劳,相當(dāng)于是一個(gè)排隊(duì)機(jī)制唧取。

而且用臨時(shí)順序節(jié)點(diǎn)的另外一個(gè)用意就是,如果某個(gè)客戶(hù)端創(chuàng)建臨時(shí)順序節(jié)點(diǎn)之后划提,不小心自己宕機(jī)了也沒(méi)關(guān)系枫弟,zk感知到那個(gè)客戶(hù)端宕機(jī),會(huì)自動(dòng)刪除對(duì)應(yīng)的臨時(shí)順序節(jié)點(diǎn)腔剂,相當(dāng)于自動(dòng)釋放鎖媒区,或者是自動(dòng)取消自己的排隊(duì)。

最后,咱們來(lái)看下用Curator框架進(jìn)行加鎖和釋放鎖的一個(gè)過(guò)程:

image.png

其實(shí)用開(kāi)源框架就是這點(diǎn)好,方便还绘。這個(gè)Curator框架的zk分布式鎖的加鎖和釋放鎖的實(shí)現(xiàn)原理和措,其實(shí)就是上面我們說(shuō)的那樣子。

但是如果你要手動(dòng)實(shí)現(xiàn)一套那個(gè)代碼的話(huà)尔店。還是有點(diǎn)麻煩的,要考慮到各種細(xì)節(jié),異常處理等等座掘。所以大家如果考慮用zk分布式鎖,可以參考下本文的思路柔滔。

END

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末溢陪,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子睛廊,更是在濱河造成了極大的恐慌形真,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,104評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件超全,死亡現(xiàn)場(chǎng)離奇詭異咆霜,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)嘶朱,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,816評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén)蛾坯,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人疏遏,你說(shuō)我怎么就攤上這事脉课。” “怎么了财异?”我有些...
    開(kāi)封第一講書(shū)人閱讀 168,697評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵下翎,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我宝当,道長(zhǎng)视事,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,836評(píng)論 1 298
  • 正文 為了忘掉前任庆揩,我火速辦了婚禮俐东,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘订晌。我一直安慰自己虏辫,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,851評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布锈拨。 她就那樣靜靜地躺著砌庄,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上娄昆,一...
    開(kāi)封第一講書(shū)人閱讀 52,441評(píng)論 1 310
  • 那天佩微,我揣著相機(jī)與錄音,去河邊找鬼萌焰。 笑死哺眯,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的扒俯。 我是一名探鬼主播奶卓,決...
    沈念sama閱讀 40,992評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼撼玄!你這毒婦竟也來(lái)了夺姑?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,899評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤掌猛,失蹤者是張志新(化名)和其女友劉穎盏浙,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體留潦,經(jīng)...
    沈念sama閱讀 46,457評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡只盹,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,529評(píng)論 3 341
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了兔院。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片殖卑。...
    茶點(diǎn)故事閱讀 40,664評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖坊萝,靈堂內(nèi)的尸體忽然破棺而出孵稽,到底是詐尸還是另有隱情,我是刑警寧澤十偶,帶...
    沈念sama閱讀 36,346評(píng)論 5 350
  • 正文 年R本政府宣布菩鲜,位于F島的核電站,受9級(jí)特大地震影響惦积,放射性物質(zhì)發(fā)生泄漏接校。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,025評(píng)論 3 334
  • 文/蒙蒙 一狮崩、第九天 我趴在偏房一處隱蔽的房頂上張望蛛勉。 院中可真熱鬧,春花似錦睦柴、人聲如沸诽凌。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,511評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)侣诵。三九已至痢法,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間杜顺,已是汗流浹背财搁。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,611評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留哑舒,地道東北人妇拯。 一個(gè)月前我還...
    沈念sama閱讀 49,081評(píng)論 3 377
  • 正文 我出身青樓幻馁,卻偏偏與公主長(zhǎng)得像洗鸵,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子仗嗦,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,675評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容