redis和zookeeper中怎么實(shí)現(xiàn)分布式鎖,很多新手對此不是很清楚,為了幫助大家解決這個難題,下面小編將為大家詳細(xì)講解,有這方面需求的人可以來學(xué)習(xí)下,希望你能有所收獲。
一、基于redis的分布式鎖實(shí)現(xiàn)
1.獲取鎖
redis是一種key-value形式的NOSQL數(shù)據(jù)庫,常用于作服務(wù)器的緩存。從redis v2.6.12開始,set命令開始變成如下格式:
SET key value [EX seconds] [PX milliseconds] [NX|XX]
除key和value外,EX是超時時間,NX表示只有在key不存在的時候才會設(shè)置key的值,而XX表示在key存在的時間才會設(shè)置key的值。NX機(jī)制就是基于redis分布式鎖的核心。能夠解決以下問題:
1)節(jié)點(diǎn)1獲取key,并且設(shè)置超時時間后,還沒來得及釋放就掛掉了——這里EX超時時間會發(fā)揮作用,超時后自動釋放鎖。
2)剛獲取到鎖,還沒來得及設(shè)置超時時間就掛了——這里設(shè)置key和設(shè)置超時時間是原子操作,如果出現(xiàn)這種情況,會返回0,即獲取不到鎖。
2.釋放鎖
為了解決非原子操作帶來的問題,常采用lua腳本實(shí)現(xiàn)。lua腳本的操作會被認(rèn)為是原子性的,類似于事務(wù)。偽代碼如下:
二、基于zookeeper的分布式鎖實(shí)現(xiàn)
zookeeper是一種分布式協(xié)調(diào)服務(wù),其中每個節(jié)點(diǎn)稱為znode,并有自己獨(dú)立的路徑。 znode有四種類型:
持久節(jié)點(diǎn):默認(rèn)的節(jié)點(diǎn)類型。創(chuàng)建節(jié)點(diǎn)的客戶端與zookeeper斷開連接后,該節(jié)點(diǎn)依舊存在 。
持久節(jié)點(diǎn)順序節(jié)點(diǎn):所謂順序節(jié)點(diǎn),就是在創(chuàng)建節(jié)點(diǎn)時,Zookeeper根據(jù)創(chuàng)建的時間順序給該節(jié)點(diǎn)名稱進(jìn)行編號:
臨時節(jié)點(diǎn):和持久節(jié)點(diǎn)相反,當(dāng)創(chuàng)建節(jié)點(diǎn)的客戶端與zookeeper斷開連接后,臨時節(jié)點(diǎn)會被刪除:
臨時順序節(jié)點(diǎn):結(jié)合和臨時節(jié)點(diǎn)和順序節(jié)點(diǎn)的特點(diǎn):在創(chuàng)建節(jié)點(diǎn)時,Zookeeper根據(jù)創(chuàng)建的時間順序給該節(jié)點(diǎn)名稱進(jìn)行編號;當(dāng)創(chuàng)建節(jié)點(diǎn)的客戶端與zookeeper斷開連接后,臨時節(jié)點(diǎn)會被刪除。
下面看看是怎樣基于上面的四類節(jié)點(diǎn)實(shí)現(xiàn)分布式鎖的。
1.獲取鎖
1)在Zookeeper當(dāng)中創(chuàng)建一個持久節(jié),當(dāng)?shù)谝粋€客戶端Client1想要獲得鎖時,需要在這個節(jié)點(diǎn)下面創(chuàng)建一個臨時順序節(jié)點(diǎn)。
2)Client1查找持久節(jié)點(diǎn)下面所有的臨時順序節(jié)點(diǎn)并排序,判斷自己所創(chuàng)建的節(jié)點(diǎn)是不是順序最靠前的一個。如果是第一個節(jié)點(diǎn),則成功獲得鎖。
3)如果再有一個客戶端 Client2 前來獲取鎖,則在持久節(jié)點(diǎn)下面再創(chuàng)建一個臨時順序節(jié)點(diǎn)Lock2。
4)Client2查找持久節(jié)點(diǎn)下面所有的臨時順序節(jié)點(diǎn)并排序,判斷自己所創(chuàng)建的節(jié)點(diǎn)Lock2是不是順序最靠前的一個,結(jié)果發(fā)現(xiàn)節(jié)點(diǎn)Lock2并不是最小的。
于是,Client2向排序僅比它靠前的節(jié)點(diǎn)Lock1注冊Watcher,用于監(jiān)聽Lock1節(jié)點(diǎn)是否存在。這意味著Client2搶鎖失敗,進(jìn)入了等待狀態(tài)。
5)如果又有一個客戶端Client3前來獲取鎖,則在持久節(jié)點(diǎn)下載再創(chuàng)建一個臨時順序節(jié)點(diǎn)Lock3。
Client3查找持久節(jié)點(diǎn)下面所有的臨時順序節(jié)點(diǎn)并排序,判斷自己所創(chuàng)建的節(jié)點(diǎn)Lock3是不是順序最靠前的一個,結(jié)果同樣發(fā)現(xiàn)節(jié)點(diǎn)Lock3并不是最小的。
于是,Client3向排序僅比它靠前的節(jié)點(diǎn)Lock2注冊Watcher,用于監(jiān)聽Lock2節(jié)點(diǎn)是否存在。這意味著Client3同樣搶鎖失敗,進(jìn)入了等待狀態(tài)。
2.釋放鎖
釋放鎖就比較簡單了,因?yàn)榍懊鎰?chuàng)建的臨時順序節(jié)點(diǎn),所以在出現(xiàn)下面兩種情況時,都會自動釋放鎖:
1)任務(wù)完成后,Client會釋放鎖。
2)任務(wù)沒完成,Client就崩潰了,也會自動釋放鎖。
看完上述內(nèi)容是否對您有幫助呢?如果還想對相關(guān)知識有進(jìn)一步的了解或閱讀更多相關(guān)文章,請關(guān)注創(chuàng)新互聯(lián)-成都網(wǎng)站建設(shè)公司行業(yè)資訊頻道,感謝您對創(chuàng)新互聯(lián)的支持。