丨如何設(shè)計(jì)更優(yōu)分布式鎖_第1頁(yè)
丨如何設(shè)計(jì)更優(yōu)分布式鎖_第2頁(yè)
丨如何設(shè)計(jì)更優(yōu)分布式鎖_第3頁(yè)
丨如何設(shè)計(jì)更優(yōu)分布式鎖_第4頁(yè)
丨如何設(shè)計(jì)更優(yōu)分布式鎖_第5頁(yè)
已閱讀5頁(yè),還剩13頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

在JVMLockJava鎖的方式就失去作用了。中,我們只需要保證一個(gè)服務(wù)節(jié)點(diǎn)即可,一定要避免多個(gè)節(jié)點(diǎn)重復(fù)給同一因?yàn)閿?shù)據(jù)庫(kù)實(shí)現(xiàn)一個(gè)分布式鎖比較簡(jiǎn)單易懂,直接基于數(shù)據(jù)庫(kù)實(shí)現(xiàn)就行了,不需要再引入第中間件,所以這是很多分布式業(yè)務(wù)實(shí)現(xiàn)分布式鎖的首選。但是數(shù)據(jù)庫(kù)實(shí)現(xiàn)的分布式鎖在一定程度上,存在性能瓶頸。CREATETABLE`order``id`int(11)NOTNULL`order_no`int(11)DEFAULT`pay_money`decimal(10,2)DEFAULT`status`int(4)DEFAULT`create_date`datetime(0)DEFAULT`delete_flag`int(4)DEFAULTPRIMARYKEY(`id`)USINGINDEX`idx_status`(`status`)USINGINDEX`idx_order`(`order_no`)USING)ENGINE=selectidfrom`order`where`order_no`='xxxx'forpublicintaddOrderRecord(Orderorder)intresult=return return 性能瓶頸了。我們?cè)诘?4講中講過(guò),在RR事務(wù)級(jí)別,select的forupdate操作是基于間隙鎖gaplock實(shí)現(xiàn)的,這是一種悲觀鎖的實(shí)現(xiàn)方式,所以存在阻塞問(wèn)題。因此在高并況下,當(dāng)有大量的請(qǐng)求進(jìn)來(lái)時(shí),大部分的請(qǐng)求都會(huì)進(jìn)行排隊(duì)等待。為了保證數(shù)據(jù)庫(kù)的穩(wěn)定性,事務(wù)的超時(shí)時(shí)間往往又設(shè)置得很小,所以就會(huì)出現(xiàn)大量事務(wù)被中斷的情況。除了數(shù)據(jù)庫(kù)實(shí)現(xiàn)分布式鎖的方式以外,我們還可以基于Zookeeper實(shí)現(xiàn)。Zookeeper是Zookeeper順序臨時(shí)節(jié)點(diǎn):Zooeeer提供一個(gè)多層級(jí)的節(jié)點(diǎn)命名空間(節(jié)點(diǎn)稱為Znoe)點(diǎn)都用一個(gè)以斜杠(/)分隔的路徑來(lái)表示,而且每個(gè)節(jié)點(diǎn)都有父節(jié)點(diǎn)(根節(jié)點(diǎn)除外),非常類似于文件系統(tǒng)。節(jié)點(diǎn)類型可以分為持久節(jié)點(diǎn)(PERISTET)、臨時(shí)節(jié)點(diǎn)(EPEMERAL),每個(gè)節(jié)點(diǎn)還能被標(biāo)記為有序性(EQUENTAL),一旦節(jié)點(diǎn)被標(biāo)記為有序性,那么整個(gè)節(jié)點(diǎn)就具有順序自增的特點(diǎn)。一般我們可以組合這幾類節(jié)點(diǎn)來(lái)創(chuàng)建我們所需要的節(jié)點(diǎn),例如,創(chuàng)建一個(gè)持久節(jié)點(diǎn)作為父節(jié)點(diǎn),在父節(jié)點(diǎn)下面創(chuàng)建臨時(shí)節(jié)點(diǎn),并標(biāo)記該臨時(shí)節(jié)點(diǎn)為有序性。Watch機(jī)制:Zookeeper還提供了另外一個(gè)重要的特性,Watcher(器)。ZooKeeper允許用戶在指定節(jié)點(diǎn)上一些Watcher,并且在一些特定觸發(fā)的時(shí)候,ZooKeeper服務(wù)端會(huì)將通知給用戶。我們熟悉了Zookeeper的這兩個(gè)特性之后,就Zookeeper是如何實(shí)現(xiàn)分布式鎖首先,我們需要建立一個(gè)父節(jié)點(diǎn),節(jié)點(diǎn)類型為持久節(jié)點(diǎn)(PERSISTENT)(EPHEMERAL),且標(biāo)記為有序性(SEQUENTIAL),稱+順序號(hào)組成特定的名字。name當(dāng)調(diào)用完共享資源后,刪除該節(jié)點(diǎn),關(guān)閉zk,進(jìn)而可以觸發(fā),釋放該鎖以上實(shí)現(xiàn)的分布式鎖是嚴(yán)格按照順序的并發(fā)鎖。一般我們還可以直接Curator框架來(lái)實(shí)現(xiàn)Zookeeper分布式鎖,代碼如下:InterProcessMutexlock=newInterProcessMutex(,if(lock.acquire(maxWait,waitUnit){{//dosomeworkinsideofthecriticalsection { 12Zookeeper實(shí)現(xiàn)的分布式鎖,例如相對(duì)數(shù)據(jù)庫(kù)實(shí)現(xiàn),有很多優(yōu)點(diǎn)。Zookeeper是集群實(shí)掉了,臨時(shí)節(jié)點(diǎn)會(huì)因?yàn)閟ession連接斷開(kāi)而自動(dòng)刪除掉。由于頻繁地創(chuàng)建和刪除結(jié)點(diǎn),加上大量的Watch,對(duì)Zookeeper集群來(lái)說(shuō),壓力非常大。且從性能上來(lái)說(shuō),其與接下來(lái)我要講的Redis實(shí)現(xiàn)的分布式鎖相比,還是存在一定相對(duì)于前兩種實(shí)現(xiàn)方式,基于Redis大部分開(kāi)發(fā)人員利用Redis實(shí)現(xiàn)分布式鎖的方式,都是使用SETNX+EXPIRE組合來(lái)實(shí)現(xiàn),在Redis2.6.12版本之前,具體實(shí)現(xiàn)代碼如下:1publicstaticbooleantryGetDistributedLock(Jedisjedis,StringlockKey,String2Longresult=jedis.setnx(lockKey,requestId);//if(result==1){////若在這里程序突然,則無(wú)法設(shè)置過(guò)期時(shí)間,將發(fā)生死jedis.expire(lockKey,expireTime);//return return10這種方式實(shí)現(xiàn)的分布式鎖,是通過(guò)setnx()方法設(shè)置鎖,如果lockKey敗,否則返回成功。設(shè)置成功之后,為了能在完成同步代碼之后成功釋放鎖,方法中還需要使用exire()方法給locKey值設(shè)置一個(gè)過(guò)期時(shí)間,確認(rèn)ey值刪除,避免出現(xiàn)鎖無(wú)法釋放,導(dǎo)致下一個(gè)線程無(wú)法獲取到鎖,即死鎖問(wèn)題。如果程序在設(shè)置過(guò)期時(shí)間之前、設(shè)置鎖之后出現(xiàn),此時(shí)如果lockKey沒(méi)有設(shè)置過(guò)期時(shí)在Redis2.6.12版本后SETNXprivatestaticfinalStringLOCK_SUCCESS=privatestaticfinalStringSET_IF_NOT_EXIST=privatestaticfinalStringSET_WITH_EXPIRE_TIME=4 **@paramjedisRedis*@paramlockKey*@paramrequestId*@paramexpireTime*@returnpublicstaticbooleantryGetDistributedLock(Jedisjedis,StringlockKey,StringStringresult=jedis.set(lockKey,SET_IF_NOT_EXIST,if(LOCK_SUCCESS.equals(result))return}return}我們也可以通過(guò)Lua來(lái)實(shí)現(xiàn)鎖的設(shè)置和過(guò)期時(shí)間的原子性,再通過(guò)jedis.eval()方法運(yùn)1//2privatefinalStringSCRIPT_LOCK="ifredis.call('setnx',KEYS[1],3//4privatefinalStringSCRIPT_UNLOCK="ifredis.call('get',KEYS[1])==SETNX這個(gè)方案是目前最優(yōu)的分布式鎖方案,但如果是在Redis集群環(huán)境下,依然存在問(wèn)題。由于RedisMaster節(jié)點(diǎn)獲取到鎖后,在沒(méi)有同步到其它節(jié)點(diǎn)時(shí),Master節(jié)點(diǎn)了,此時(shí)新的Master節(jié)點(diǎn)依然可以獲取鎖,所以多個(gè)RedlockRedisson由Redis推出,它是一個(gè)在Redis的基礎(chǔ)上實(shí)現(xiàn)的Java駐內(nèi)存數(shù)據(jù)網(wǎng)(In-MemoryDataGrid)。它不僅提供了一系列的分布式的Java常用對(duì)象,還提供了許多分布式服務(wù)。Redisson是基于netty通信框架實(shí)現(xiàn)的,所以支持非阻塞通信,性能相對(duì)于我們熟悉的Jedis會(huì)好一些。Redisson中實(shí)現(xiàn)了Redis分布式鎖,且支持單點(diǎn)模式和集群模式。在集群模式下,Redisson使用了Redlock算法,避免在Master節(jié)點(diǎn)切換到另外一個(gè)Master時(shí),多個(gè)應(yīng)用同時(shí)獲得鎖。我們可以通過(guò)一個(gè)應(yīng)用服務(wù)獲取分布式鎖的流程,了解下Redlock算在不同的節(jié)點(diǎn)上使用單個(gè)實(shí)例獲取鎖的方式去獲得鎖,且每次獲取鎖都有超時(shí)時(shí)間,如果請(qǐng)求超時(shí),則認(rèn)為該節(jié)點(diǎn)不可用。當(dāng)應(yīng)用服務(wù)成功獲取鎖的Redis節(jié)點(diǎn)超過(guò)半數(shù)(N/2+1,N為節(jié)點(diǎn)數(shù))時(shí),并且獲取鎖消耗的實(shí)際時(shí)間不超過(guò)鎖的過(guò)期時(shí)間,則獲取鎖成功。1jar實(shí)現(xiàn)RedissonpublicRedissonredisson()Configconfig=new.setScanInterval(2000) return11longwaitTimeout=longleaseTime=RLocklock1=redissonRLocklock2=redissonRLocklock3=redisson6RedissonRedLockredLock=newRedissonRedLock(lock1,lock2,//同時(shí)加鎖:lock1lock2//ZookeeperRedis的性能是最好的,Zookeeper次之,數(shù)據(jù)庫(kù)。從實(shí)現(xiàn)方式和可靠性來(lái)說(shuō),ZookeeperZookeeper我們知道Redis分布式鎖在集群環(huán)境下會(huì)出現(xiàn)不同應(yīng)用服務(wù)同時(shí)獲得鎖的可能,而RedissonRedlockRedisson期待在留言區(qū)看到你的答案。也歡迎你點(diǎn)擊“請(qǐng)朋友讀”,把今天的內(nèi)容給身邊的朋 歸科技所有 不得售賣。頁(yè)面已增加防盜追蹤,將依法其上一 40|答疑課堂:MySQL中InnoDB的知識(shí)點(diǎn)串下一 42|系統(tǒng)的分布式事務(wù)調(diào)言言不一定,因?yàn)槿绻褐杏袀€(gè)rd,abcde,如果發(fā)生網(wǎng)絡(luò)分區(qū),abc在一個(gè)分區(qū),d一個(gè)分區(qū),客戶端向abc申請(qǐng)鎖成功,在節(jié)點(diǎn)mastr異步同步sa的時(shí)候,mastr宕機(jī)了,sae,然后c的sa又和d在一個(gè)分區(qū)里

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論