自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

年底裸辭準(zhǔn)備面試,我用七張圖畫(huà)了ZK分布式鎖

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

一、寫(xiě)在前面

這篇文章再給大家聊一下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)景?

如果大家對(duì)zk還不太了解,建議先百度一下,快速了解一些基本概念,比如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ì)弄成如下的樣子:

大家看,客戶(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è)集合:

接著客戶(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è)嘗試加分布式鎖的人?。?/p>

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

接著假如說(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)似于:

大家看看下面的圖:

客戶(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)似于:

同時(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ì)他的上一個(gè)順序節(jié)點(diǎn)加一個(gè)監(jiān)聽(tīng)器。zk天然就可以實(shí)現(xiàn)對(duì)某個(gè)節(jié)點(diǎn)的監(jiān)聽(tīng)。

我們舉例說(shuō)明,客戶(hù)端B的順序節(jié)點(diǎn)是:

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

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

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

這個(gè)節(jié)點(diǎn)加一個(gè)監(jiān)聽(tīng)器,監(jiān)聽(tīng)這個(gè)節(jié)點(diǎn)是否被刪除等變化!

說(shuō)了那么多,老規(guī)矩,給大家來(lái)一張圖,直觀的感受一下:

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

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

這個(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)被刪除了,有人釋放了鎖。

我們一起來(lái)看看下面的圖,體會(huì)一下這個(gè)過(guò)程:

此時(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í)為:

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

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

最后,再給大家來(lái)一張圖,大伙兒順著圖仔細(xì)的捋一捋這整個(gè)過(guò)程:

三、總結(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ò)程:

其實(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分布式鎖,可以參考下本文的思路。?

責(zé)任編輯:武曉燕 來(lái)源: 今日頭條
相關(guān)推薦

2021-10-25 10:21:59

ZK分布式鎖ZooKeeper

2020-11-16 12:55:41

Redis分布式鎖Zookeeper

2019-07-16 09:22:10

RedisZookeeper分布式鎖

2019-06-19 15:40:06

分布式鎖RedisJava

2020-12-15 10:20:24

分布式鎖RedisZookeeper

2018-07-17 08:14:22

分布式分布式鎖方位

2021-08-20 14:26:17

鴻蒙HarmonyOS應(yīng)用

2021-07-16 07:57:34

ZooKeeperCurator源碼

2019-02-26 09:51:52

分布式鎖RedisZookeeper

2022-08-04 08:45:50

Redisson分布式鎖工具

2021-10-09 11:34:59

MySQL分布式鎖庫(kù)存

2018-11-27 16:17:13

分布式Tomcat

2021-11-26 06:43:19

Java分布式

2022-07-06 08:01:05

數(shù)據(jù)庫(kù)分布式

2024-09-24 16:30:46

分布式鎖Redis數(shù)據(jù)中間件

2022-08-11 18:27:50

面試Redis分布式鎖

2024-04-17 08:42:15

Go語(yǔ)言分布式鎖

2022-03-04 09:54:04

Redis分布式鎖腳本

2021-07-06 08:37:29

Redisson分布式

2023-09-22 08:00:00

分布式鎖Redis
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)