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

下載本文檔

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

文檔簡介

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

溫馨提示

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

最新文檔

評論

0/150

提交評論