有了zookeeper的一致性文件系統(tǒng)梢薪,鎖的問(wèn)題變得容易。鎖服務(wù)可以分為兩類
保持獨(dú)占
將zookeeper上的一個(gè)znode看作是一把鎖尝哆,通過(guò)createznode的方式來(lái)實(shí)現(xiàn)秉撇。所有客戶端都去創(chuàng)建 /distribute_lock 節(jié)點(diǎn),最終成功創(chuàng)建的那個(gè)客戶端也即擁有了這把鎖较解。用完刪除掉自己創(chuàng)建的distribute_lock 節(jié)點(diǎn)就釋放出鎖畜疾。控制時(shí)序。 /distribute_lock 已經(jīng)預(yù)先存在印衔,所有客戶端在它下面創(chuàng)建臨時(shí)順序編號(hào)目錄節(jié)點(diǎn)啡捶,和選master一樣,編號(hào)最小的獲得鎖奸焙,用完刪除瞎暑,依次方便。
zk_distributed_locker1.png
在獲取分布式鎖的時(shí)候在locker節(jié)點(diǎn)下創(chuàng)建臨時(shí)順序節(jié)點(diǎn)与帆,釋放鎖的時(shí)候刪除該臨時(shí)節(jié)點(diǎn)了赌。
- 客戶端調(diào)用createNode方法在locker下創(chuàng)建臨時(shí)順序節(jié)點(diǎn)
- 調(diào)用getChildren(“l(fā)ocker”)來(lái)獲取locker下面的所有子節(jié)點(diǎn),注意此時(shí)不用設(shè)置任何Watcher玄糟。
- 客戶端獲取到所有的子節(jié)點(diǎn)path之后勿她,如果發(fā)現(xiàn)自己創(chuàng)建的節(jié)點(diǎn)在所有創(chuàng)建的子節(jié)點(diǎn)序號(hào)最小,那么就認(rèn)為該客戶端獲取到了鎖阵翎。
- 如果發(fā)現(xiàn)自己創(chuàng)建的節(jié)點(diǎn)并非locker所有子節(jié)點(diǎn)中最小的逢并,說(shuō)明自己還沒(méi)有獲取到鎖,此時(shí)客戶端需要找到比自己小的那個(gè)節(jié)點(diǎn)郭卫,然后對(duì)其調(diào)用exist()方法砍聊,同時(shí)對(duì)其注冊(cè)事件監(jiān)聽器。
- 之后贰军,讓這個(gè)被關(guān)注的節(jié)點(diǎn)刪除玻蝌,則客戶端的Watcher會(huì)收到相應(yīng)通知,此時(shí)再次判斷自己創(chuàng)建的節(jié)點(diǎn)是否是locker子節(jié)點(diǎn)中序號(hào)最小的词疼,如果是則獲取到了鎖俯树,如果不是則重復(fù)以上步驟繼續(xù)獲取到比自己小的一個(gè)節(jié)點(diǎn)并注冊(cè)監(jiān)聽。
zk_distributed_locker2.png