分布式場(chǎng)景中的數(shù)據(jù)一致性問(wèn)題一直是一個(gè)比較重要的話題。分布式的CAP理論告訴我們“任何一個(gè)分布式系統(tǒng)都無(wú)法同時(shí)滿足一致性(Consistency)嗦篱、可用性(Availability)和分區(qū)容錯(cuò)性(Partition tolerance)贺纲,最多只能同時(shí)滿足兩項(xiàng)竿痰。”所以软棺,很多系統(tǒng)在設(shè)計(jì)之初就要對(duì)這三者做出取舍红竭。在互聯(lián)網(wǎng)領(lǐng)域的絕大多數(shù)的場(chǎng)景中,都需要犧牲強(qiáng)一致性來(lái)?yè)Q取系統(tǒng)的高可用性,系統(tǒng)往往只需要保證“最終一致性”茵宪,只要這個(gè)最終時(shí)間是在用戶可以接受的范圍內(nèi)即可最冰。
在很多場(chǎng)景中,我們?yōu)榱吮WC數(shù)據(jù)的最終一致性眉厨,需要很多的技術(shù)方案來(lái)支持锌奴,比如分布式事務(wù)、分布式鎖等憾股。有的時(shí)候鹿蜀,我們需要保證一個(gè)方法在同一時(shí)間內(nèi)只能被同一個(gè)線程執(zhí)行。
數(shù)據(jù)庫(kù)實(shí)現(xiàn)分布式鎖的優(yōu)點(diǎn)
直接借助數(shù)據(jù)庫(kù)服球,容易理解茴恰。
數(shù)據(jù)庫(kù)實(shí)現(xiàn)分布式鎖的缺點(diǎn)
會(huì)有各種各樣的問(wèn)題,在解決問(wèn)題的過(guò)程中會(huì)使整個(gè)方案變得越來(lái)越復(fù)雜斩熊。
操作數(shù)據(jù)庫(kù)需要一定的開銷往枣,性能問(wèn)題需要考慮。
使用數(shù)據(jù)庫(kù)的行級(jí)鎖并不一定靠譜粉渠,尤其是當(dāng)我們的鎖表并不大的時(shí)候分冈。
使用緩存實(shí)現(xiàn)分布式鎖的優(yōu)點(diǎn)
性能好,實(shí)現(xiàn)起來(lái)較為方便霸株。
使用緩存實(shí)現(xiàn)分布式鎖的缺點(diǎn)
通過(guò)超時(shí)時(shí)間來(lái)控制鎖的失效時(shí)間并不是十分的靠譜雕沉。
基于Zookeeper實(shí)現(xiàn)分布式鎖
基于zookeeper臨時(shí)有序節(jié)點(diǎn)可以實(shí)現(xiàn)的分布式鎖。
大致思想即為:每個(gè)客戶端對(duì)某個(gè)方法加鎖時(shí)去件,在zookeeper上的與該方法對(duì)應(yīng)的指定節(jié)點(diǎn)的目錄下坡椒,生成一個(gè)唯一的瞬時(shí)有序節(jié)點(diǎn)。 判斷是否獲取鎖的方式很簡(jiǎn)單尤溜,只需要判斷有序節(jié)點(diǎn)中序號(hào)最小的一個(gè)倔叼。 當(dāng)釋放鎖的時(shí)候,只需將這個(gè)瞬時(shí)節(jié)點(diǎn)刪除即可宫莱。同時(shí)丈攒,其可以避免服務(wù)宕機(jī)導(dǎo)致的鎖無(wú)法釋放,而產(chǎn)生的死鎖問(wèn)題梢睛。
來(lái)看下Zookeeper能不能解決前面提到的問(wèn)題肥印。
鎖無(wú)法釋放?使用Zookeeper可以有效的解決鎖無(wú)法釋放的問(wèn)題绝葡,因?yàn)樵趧?chuàng)建鎖的時(shí)候,客戶端會(huì)在ZK中創(chuàng)建一個(gè)臨時(shí)節(jié)點(diǎn)腹鹉,一旦客戶端獲取到鎖之后突然掛掉(Session連接斷開)藏畅,那么這個(gè)臨時(shí)節(jié)點(diǎn)就會(huì)自動(dòng)刪除掉。其他客戶端就可以再次獲得鎖。
非阻塞鎖愉阎?使用Zookeeper可以實(shí)現(xiàn)阻塞的鎖绞蹦,客戶端可以通過(guò)在ZK中創(chuàng)建順序節(jié)點(diǎn),并且在節(jié)點(diǎn)上綁定監(jiān)聽器榜旦,一旦節(jié)點(diǎn)有變化幽七,Zookeeper會(huì)通知客戶端,客戶端可以檢查自己創(chuàng)建的節(jié)點(diǎn)是不是當(dāng)前所有節(jié)點(diǎn)中序號(hào)最小的溅呢,如果是澡屡,那么自己就獲取到鎖,便可以執(zhí)行業(yè)務(wù)邏輯了咐旧。
不可重入驶鹉?使用Zookeeper也可以有效的解決不可重入的問(wèn)題,客戶端在創(chuàng)建節(jié)點(diǎn)的時(shí)候铣墨,把當(dāng)前客戶端的主機(jī)信息和線程信息直接寫入到節(jié)點(diǎn)中室埋,下次想要獲取鎖的時(shí)候和當(dāng)前最小的節(jié)點(diǎn)中的數(shù)據(jù)比對(duì)一下就可以了。如果和自己的信息一樣伊约,那么自己直接獲取到鎖姚淆,如果不一樣就再創(chuàng)建一個(gè)臨時(shí)的順序節(jié)點(diǎn),參與排隊(duì)屡律。
單點(diǎn)問(wèn)題腌逢?使用Zookeeper可以有效的解決單點(diǎn)問(wèn)題,ZK是集群部署的疹尾,只要集群中有半數(shù)以上的機(jī)器存活上忍,就可以對(duì)外提供服務(wù)。