在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

分析3種分布式鎖的設(shè)計(jì)與實(shí)現(xiàn)

電子工程師 ? 來(lái)源:未知 ? 作者:李倩 ? 2018-11-26 11:26 ? 次閱讀

多線程情況下對(duì)共享資源的操作需要加鎖,避免數(shù)據(jù)被寫亂,在分布式系統(tǒng)中,這個(gè)問(wèn)題也是存在的,此時(shí)就需要一個(gè)分布式鎖服務(wù)。常見(jiàn)的分布式鎖實(shí)現(xiàn)一般是基于DB、Redis、zookeeper。下面筆者會(huì)按照順序分析下這3種分布式鎖的設(shè)計(jì)與實(shí)現(xiàn),想直接看分布式鎖總結(jié)的小伙伴可直接翻到文檔末尾處。

分布式鎖的實(shí)現(xiàn)由多種方式,但是不管怎樣,分布式鎖一般要有以下特點(diǎn):

排他性:任意時(shí)刻,只能有一個(gè)client能獲取到鎖

容錯(cuò)性:分布式鎖服務(wù)一般要滿足AP,也就是說(shuō),只要分布式鎖服務(wù)集群節(jié)點(diǎn)大部分存活,client就可以進(jìn)行加鎖解鎖操作

避免死鎖:分布式鎖一定能得到釋放,即使client在釋放之前崩潰或者網(wǎng)絡(luò)不可達(dá)

除了以上特點(diǎn)之外,分布式鎖最好也能滿足可重入、高性能、阻塞鎖特性(AQS這種,能夠及時(shí)從阻塞狀態(tài)喚醒)等,下面就話不多說(shuō),趕緊上(開(kāi)往分布式鎖的設(shè)計(jì)與實(shí)現(xiàn)的)車~

DB鎖

在數(shù)據(jù)庫(kù)新建一張表用于控制并發(fā)控制,表結(jié)構(gòu)可以如下所示:

CREATETABLE`lock_table`(`id`int(11)unsignedNOTNULLCOMMENT'主鍵',`key_id`bigint(20)NOTNULLCOMMENT'分布式key',`memo`varchar(43)NOTNULLDEFAULT''COMMENT'可記錄操作內(nèi)容',`update_time`datetimeNOTNULLCOMMENT'更新時(shí)間',PRIMARYKEY(`id`,`key_id`),UNIQUEKEY`key_id`(`key_id`)USINGBTREE)ENGINE=InnoDBDEFAULTCHARSET=utf8;

key_id作為分布式key用來(lái)并發(fā)控制,memo可用來(lái)記錄一些操作內(nèi)容(比如memo可用來(lái)支持重入特性,標(biāo)記下當(dāng)前加鎖的client和加鎖次數(shù))。將key_id設(shè)置為唯一索引,保證了針對(duì)同一個(gè)key_id只有一個(gè)加鎖(數(shù)據(jù)插入)能成功。此時(shí)lock和unlock偽代碼如下:

deflock:execsql:insertintolock_table(key_id,memo,update_time)values(key_id,memo,NOW())ifresult==true:returntrueelse:returnfalsedefunlock:execsql:deletefromlock_tablewherekey_id='key_id'andmemo='memo'

注意,偽代碼中的lock操作是非阻塞鎖,也就是tryLock,如果想實(shí)現(xiàn)阻塞(或者阻塞超時(shí))加鎖,只修反復(fù)執(zhí)行l(wèi)ock偽代碼直到加鎖成功為止即可。基于DB的分布式鎖其實(shí)有一個(gè)問(wèn)題,那就是如果加鎖成功后,client端宕機(jī)或者由于網(wǎng)絡(luò)原因?qū)е聸](méi)有解鎖,那么其他client就無(wú)法對(duì)該key_id進(jìn)行加鎖并且無(wú)法釋放了。為了能夠讓鎖失效,需要在應(yīng)用層加上定時(shí)任務(wù),去刪除過(guò)期還未解鎖的記錄,比如刪除2分鐘前未解鎖的偽代碼如下:

defclear_timeout_lock:execsql:deletefromlock_tablewhereupdate_time

因?yàn)閱螌?shí)例DB的TPS一般為幾百,所以基于DB的分布式性能上限一般也是1k以下,一般在并發(fā)量不大的場(chǎng)景下該分布式鎖是滿足需求的,不會(huì)出現(xiàn)性能問(wèn)題。不過(guò)DB作為分布式鎖服務(wù)需要考慮單點(diǎn)問(wèn)題,對(duì)于分布式系統(tǒng)來(lái)說(shuō)是不允許出現(xiàn)單點(diǎn)的,一般通過(guò)數(shù)據(jù)庫(kù)的同步復(fù)制,以及使用vip切換Master就能解決這個(gè)問(wèn)題。

以上DB分布式鎖是通過(guò)insert來(lái)實(shí)現(xiàn)的,如果加鎖的數(shù)據(jù)已經(jīng)在數(shù)據(jù)庫(kù)中存在,那么用select xxx where key_id = xxx for udpate方式來(lái)做也是可以的。

Redis鎖

Redis鎖是通過(guò)以下命令對(duì)資源進(jìn)行加鎖:

setkey_idkey_valueNXPXexpireTime

其中,set nx命令只會(huì)在key不存在時(shí)給key進(jìn)行賦值,px用來(lái)設(shè)置key過(guò)期時(shí)間,key_value一般是隨機(jī)值,用來(lái)保證釋放鎖的安全性(釋放時(shí)會(huì)判斷是否是之前設(shè)置過(guò)的隨機(jī)值,只有是才釋放鎖)。由于資源設(shè)置了過(guò)期時(shí)間,一定時(shí)間后鎖會(huì)自動(dòng)釋放。

set nx保證并發(fā)加鎖時(shí)只有一個(gè)client能設(shè)置成功(Redis內(nèi)部是單線程,并且數(shù)據(jù)存在內(nèi)存中,也就是說(shuō)redis內(nèi)部執(zhí)行命令是不會(huì)有多線程同步問(wèn)題的),此時(shí)的lock/unlock偽代碼如下:

deflock:if(redis.call('set',KEYS[1],ARGV[1],'ex',ARGV[2],'nx'))thenreturntrueendreturnfalsedefunlock:if(redis.call('get',KEYS[1])==ARGV[1])thenredis.call('del',KEYS[1])returntrueendreturnfalse

分布式鎖服務(wù)中的一個(gè)問(wèn)題

如果一個(gè)獲取到鎖的client因?yàn)槟撤N原因?qū)е聸](méi)能及時(shí)釋放鎖,并且redis因?yàn)槌瑫r(shí)釋放了鎖,另外一個(gè)client獲取到了鎖,此時(shí)情況如下圖所示:

那么如何解決這個(gè)問(wèn)題呢,一種方案是引入鎖續(xù)約機(jī)制,也就是獲取鎖之后,釋放鎖之前,會(huì)定時(shí)進(jìn)行鎖續(xù)約,比如以鎖超時(shí)時(shí)間的1/3為間隔周期進(jìn)行鎖續(xù)約。

關(guān)于開(kāi)源的redis的分布式鎖實(shí)現(xiàn)有很多,比較出名的有redisson、百度的dlock,關(guān)于分布式鎖,筆者也寫了一個(gè)簡(jiǎn)易版的分布式鎖redis-lock,主要是增加了鎖續(xù)約和可同時(shí)針對(duì)多個(gè)key加鎖的機(jī)制。

對(duì)于高可用性,一般可以通過(guò)集群或者master-slave來(lái)解決,redis鎖優(yōu)勢(shì)是性能出色,劣勢(shì)就是由于數(shù)據(jù)在內(nèi)存中,一旦緩存服務(wù)宕機(jī),鎖數(shù)據(jù)就丟失了。像redis自帶復(fù)制功能,可以對(duì)數(shù)據(jù)可靠性有一定的保證,但是由于復(fù)制也是異步完成的,因此依然可能出現(xiàn)master節(jié)點(diǎn)寫入鎖數(shù)據(jù)而未同步到slave節(jié)點(diǎn)的時(shí)候宕機(jī),鎖數(shù)據(jù)丟失問(wèn)題。

zookeeper分布式鎖

ZooKeeper是一個(gè)高可用的分布式協(xié)調(diào)服務(wù),由雅虎創(chuàng)建,是Google Chubby的開(kāi)源實(shí)現(xiàn)。ZooKeeper提供了一項(xiàng)基本的服務(wù):分布式鎖服務(wù)。zookeeper重要的3個(gè)特征是:zab協(xié)議、node存儲(chǔ)模型和watcher機(jī)制。通過(guò)zab協(xié)議保證數(shù)據(jù)一致性,zookeeper集群部署保證可用性,node存儲(chǔ)在內(nèi)存中,提高了數(shù)據(jù)操作性能,使用watcher機(jī)制,實(shí)現(xiàn)了通知機(jī)制(比如加鎖成功的client釋放鎖時(shí)可以通知到其他client)。

zookeeper node模型支持臨時(shí)節(jié)點(diǎn)特性,即client寫入的數(shù)據(jù)時(shí)臨時(shí)數(shù)據(jù),當(dāng)客戶端宕機(jī)時(shí)臨時(shí)數(shù)據(jù)會(huì)被刪除,這樣就不需要給鎖增加超時(shí)釋放機(jī)制了。當(dāng)針對(duì)同一個(gè)path并發(fā)多個(gè)創(chuàng)建請(qǐng)求時(shí),只有一個(gè)client能創(chuàng)建成功,這個(gè)特性用來(lái)實(shí)現(xiàn)分布式鎖。注意:如果client端沒(méi)有宕機(jī),由于網(wǎng)絡(luò)原因?qū)е聑ookeeper服務(wù)與client心跳失敗,那么zookeeper也會(huì)把臨時(shí)數(shù)據(jù)給刪除掉的,這時(shí)如果client還在操作共享數(shù)據(jù),是有一定風(fēng)險(xiǎn)的。

基于zookeeper實(shí)現(xiàn)分布式鎖,相對(duì)于基于redis和DB的實(shí)現(xiàn)來(lái)說(shuō),使用上更容易,效率與穩(wěn)定性較好。curator封裝了對(duì)zookeeper的api操作,同時(shí)也封裝了一些高級(jí)特性,如:Cache事件監(jiān)聽(tīng)、選舉、分布式鎖、分布式計(jì)數(shù)器、分布式Barrier等,使用curator進(jìn)行分布式加鎖示例如下:

org.apache.curatorcurator-framework2.12.0 org.apache.curatorcurator-recipes2.12.0{try{lock.acquire();try{System.out.println("zookeeperacquiresuccess:"+Thread.currentThread().getName());Thread.sleep(1000);}catch(Exceptione){e.printStackTrace();}finally{lock.release();}}catch(Exceptionex){ex.printStackTrace();}};ExecutorServiceexecutor=Executors.newFixedThreadPool(10);for(inti=0;i

總結(jié)

從上面介紹的3種分布式鎖的設(shè)計(jì)與實(shí)現(xiàn)中,我們可以看出每種實(shí)現(xiàn)都有各自的特點(diǎn),針對(duì)潛在的問(wèn)題有不同的解決方案,歸納如下:

性能:redis > zookeeper > db。

避免死鎖:DB通過(guò)應(yīng)用層設(shè)置定時(shí)任務(wù)來(lái)刪除過(guò)期還未釋放的鎖,redis通過(guò)設(shè)置超時(shí)時(shí)間來(lái)解決,而zookeeper是通過(guò)臨時(shí)節(jié)點(diǎn)來(lái)解決。

可用性:DB可通過(guò)數(shù)據(jù)庫(kù)同步復(fù)制,vip切換master來(lái)解決,redis可通過(guò)集群或者master-slave方式來(lái)解決,zookeeper本身自己是通過(guò)zab協(xié)議集群部署來(lái)解決的。注意,DB和redis的復(fù)制一般都是異步的,也就是說(shuō)某些時(shí)刻分布式鎖發(fā)生故障可能存在數(shù)據(jù)不一致問(wèn)題,而zookeeper本身通過(guò)zab協(xié)議保證集群內(nèi)(至少n/2+1個(gè))節(jié)點(diǎn)數(shù)據(jù)一致性。

鎖喚醒:DB和redis分布式鎖一般不支持喚醒機(jī)制(也可以通過(guò)應(yīng)用層自己做輪詢檢測(cè)鎖是否空閑,空閑就喚醒內(nèi)部加鎖線程),zookeeper可通過(guò)本身的watcher/notify機(jī)制來(lái)做。

使用分布式鎖,安全性上和多線程(同一個(gè)進(jìn)程內(nèi))加鎖是沒(méi)法比的,可能由于網(wǎng)絡(luò)原因,分布式鎖服務(wù)(因?yàn)槌瑫r(shí)或者認(rèn)為client掛了)將加鎖資源給刪除了,如果client端繼續(xù)操作共享資源,此時(shí)是有隱患的。因此,對(duì)于分布式鎖,一個(gè)是盡量提高分布式鎖服務(wù)的可用性,另一個(gè)就是要部署同一內(nèi)網(wǎng),盡量降低網(wǎng)絡(luò)問(wèn)題發(fā)生幾率。這樣來(lái)看,貌似分布式鎖服務(wù)不是“完美”的(PS:技術(shù)貌似也不好做到十全十美 :( ),那么開(kāi)發(fā)人員該如何選擇分布式鎖呢?最好是結(jié)合自己的業(yè)務(wù)實(shí)際場(chǎng)景,來(lái)選擇不同的分布式鎖實(shí)現(xiàn),一般來(lái)說(shuō),基于redis的分布式鎖服務(wù)應(yīng)用較多。

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 數(shù)據(jù)庫(kù)
    +關(guān)注

    關(guān)注

    7

    文章

    3826

    瀏覽量

    64510
  • 多線程
    +關(guān)注

    關(guān)注

    0

    文章

    278

    瀏覽量

    20018

原文標(biāo)題:一文弄懂“分布式鎖”

文章出處:【微信號(hào):DBDevs,微信公眾號(hào):數(shù)據(jù)分析與開(kāi)發(fā)】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    Redis 分布式的正確實(shí)現(xiàn)方式

    分布式一般有三實(shí)現(xiàn)方式:1. 數(shù)據(jù)庫(kù)樂(lè)觀;2. 基于Redis的分布式
    的頭像 發(fā)表于 05-31 14:19 ?3610次閱讀

    Java:Redis分布式的原理和案例

    要介紹分布式,首先要提到與分布式鎖相對(duì)應(yīng)的是線程、進(jìn)程
    的頭像 發(fā)表于 07-01 11:49 ?3885次閱讀

    分布式的基本原理和案例實(shí)現(xiàn)

    前面我們有聊過(guò)樂(lè)觀和悲觀實(shí)現(xiàn),均是對(duì)于單體架構(gòu)的場(chǎng)景下的實(shí)現(xiàn)。那么現(xiàn)在我們來(lái)總結(jié)看下分布式情況下如何
    的頭像 發(fā)表于 07-01 14:53 ?3347次閱讀
    <b class='flag-5'>分布式</b><b class='flag-5'>鎖</b>的基本原理和案例<b class='flag-5'>實(shí)現(xiàn)</b>

    分布式的設(shè)計(jì)與實(shí)現(xiàn)

    今天跟大家探討一下分布式的設(shè)計(jì)與實(shí)現(xiàn)。希望對(duì)大家有幫助,如果有不正確的地方,歡迎指出,一起學(xué)習(xí),一起進(jìn)步哈。
    的頭像 發(fā)表于 05-13 15:36 ?1784次閱讀

    深入理解redis分布式

    系統(tǒng)不同進(jìn)程共同訪問(wèn)共享資源的一實(shí)現(xiàn)。如果不同的系統(tǒng)或同一個(gè)系統(tǒng)的不同主機(jī)之間共享了某個(gè)臨界資源,往往需要互斥來(lái)防止彼此干擾,以保證一致性。 業(yè)界流行的分布式
    的頭像 發(fā)表于 10-08 14:13 ?978次閱讀
    深入理解redis<b class='flag-5'>分布式</b><b class='flag-5'>鎖</b>

    Redis實(shí)現(xiàn)分布式的幾種方案

    本文將介紹什么是分布式,以及使用Redis實(shí)現(xiàn)分布式的幾種方案。 前言 了解分布式
    的頭像 發(fā)表于 10-11 15:19 ?688次閱讀

    什么是分布式 Redis的五分布式方案

    本地加鎖的方式在分布式的場(chǎng)景下不適用,所以本文我們來(lái)探討下如何引入分布式解決本地的問(wèn)題。本篇所有代碼和業(yè)務(wù)基于我的開(kāi)源項(xiàng)目 PassJava。
    發(fā)表于 10-23 11:35 ?1231次閱讀
    什么是<b class='flag-5'>分布式</b><b class='flag-5'>鎖</b> Redis的五<b class='flag-5'>種</b><b class='flag-5'>分布式</b><b class='flag-5'>鎖</b>方案

    redis分布式如何實(shí)現(xiàn)

    Redis分布式是一基于Redis實(shí)現(xiàn)的機(jī)制,可以用于多個(gè)進(jìn)程或多臺(tái)服務(wù)器之間對(duì)共享資源的并發(fā)訪問(wèn)控制。在分布式系統(tǒng)中,由于多個(gè)進(jìn)程或多
    的頭像 發(fā)表于 11-16 11:29 ?549次閱讀

    redis分布式可能出現(xiàn)的問(wèn)題

    Redis分布式是一常用的機(jī)制,用于解決多個(gè)進(jìn)程或多臺(tái)服務(wù)器對(duì)共享資源的并發(fā)訪問(wèn)問(wèn)題。然而,由于分布式環(huán)境的復(fù)雜性,使用Redis
    的頭像 發(fā)表于 11-16 11:40 ?1419次閱讀

    redis分布式死鎖處理方案

    引言: 隨著分布式系統(tǒng)的廣泛應(yīng)用,尤其是在大規(guī)模并發(fā)操作下,對(duì)并發(fā)控制的需求越來(lái)越高。Redis分布式作為一常見(jiàn)的分布式
    的頭像 發(fā)表于 11-16 11:44 ?1770次閱讀

    redis分布式的應(yīng)用場(chǎng)景有哪些

    Redis分布式是一基于Redis實(shí)現(xiàn)分布式機(jī)制,可以在
    的頭像 發(fā)表于 12-04 11:21 ?1454次閱讀

    redis分布式三個(gè)方法

    的三常見(jiàn)的分布式實(shí)現(xiàn)方法:基于SETNX命令的簡(jiǎn)單分布式、基于SET命令的帶過(guò)期時(shí)間的
    的頭像 發(fā)表于 12-04 11:22 ?1485次閱讀

    如何實(shí)現(xiàn)Redis分布式

    機(jī)制,下面將詳細(xì)介紹如何實(shí)現(xiàn)Redis分布式。 一、引言 在分布式系統(tǒng)中,多個(gè)節(jié)點(diǎn)可能同時(shí)讀寫同一共享資源。如果沒(méi)有實(shí)現(xiàn)互斥訪問(wèn)和同步機(jī)制
    的頭像 發(fā)表于 12-04 11:24 ?722次閱讀

    淺析Redis 分布式解決方案

    Redis 分布式解決方案是一基于Redis實(shí)現(xiàn)分布式機(jī)制,可以確保在
    的頭像 發(fā)表于 12-04 14:00 ?511次閱讀

    分布式的三實(shí)現(xiàn)方式

    分布式的三實(shí)現(xiàn)方式? 分布式是在分布式系統(tǒng)中用
    的頭像 發(fā)表于 12-28 10:01 ?929次閱讀
    主站蜘蛛池模板: 2022国产情侣真实露脸在线| 1024你懂的在线观看| 国产精品欧美一区二区| 国产色视频一区| 操美女网址| 午夜在线免费观看视频| 天天干天天操天天碰| 久热福利视频| 性欧美高清极品xx| 亚洲一区三区| 怡红院日本一道日本久久| 亚洲国产成人精彩精品 | 俺要操| 高清欧美性xxxx成熟| 女的扒开尿口让男人桶爽| 一级特黄aa大片一又好看| 色碰人色碰人视频| 清纯漂亮小美女准备啪啪| 欧美黄色片视频| 欧美午夜性春猛xxxx| 清朝荒淫牲艳史在线播放| 一级特色黄色片| 人与性www| 国产精品99r8免费视频2022| 午夜久| 操国产美女| 美女扒开尿口让男人捅| 婷婷六月色| 精品国产欧美一区二区最新| 97色网| 成人免费黄色| 91麻豆麻豆| 欧美一级艳片视频免费观看| 国产乱人视频免费播放| 人人澡 人人澡 人人看| 在线99热| 四虎在线免费视频| 国产永久视频夜色资源网| 欧美日韩伦理| 亚洲一区二区免费视频| 四虎a级欧美在线观看|