前面我們有聊過(guò)樂(lè)觀鎖和悲觀鎖的實(shí)現(xiàn),均是對(duì)于單體架構(gòu)的場(chǎng)景下的實(shí)現(xiàn)。那么現(xiàn)在我們來(lái)總結(jié)看下分布式情況下如何實(shí)現(xiàn)鎖機(jī)制。
常見(jiàn)場(chǎng)景
我們來(lái)看下一個(gè)場(chǎng)景,假設(shè)我現(xiàn)在在分布式系統(tǒng)下要做一個(gè)業(yè)務(wù)邏輯的消費(fèi)動(dòng)作,我如何保證我的消費(fèi)動(dòng)作只被消費(fèi)一次不重復(fù)消費(fèi)?有的同學(xué)第一時(shí)間就想到了MQ,諸如Zookeeper。我們今天暫不談MQ,那其實(shí)核心還是代碼執(zhí)行的鎖機(jī)制問(wèn)題。
我們?cè)賮?lái)看一個(gè)場(chǎng)景,我們有個(gè)接口需要經(jīng)常查數(shù)據(jù)庫(kù)DB數(shù)據(jù),如果場(chǎng)景允許我們經(jīng)常會(huì)對(duì)其加一層緩存,并設(shè)定過(guò)期時(shí)間。假設(shè)在某一瞬間,緩存過(guò)期,但此時(shí)并發(fā)量又很大,會(huì)有大量的請(qǐng)求穿透去數(shù)據(jù)庫(kù)請(qǐng)求數(shù)據(jù),造成緩存雪崩效應(yīng)。于是,我們就可以考慮加鎖機(jī)制,只讓一個(gè)請(qǐng)求去執(zhí)行查詢DB更新緩存的操作。
基本原理
回顧下我們之前聊到鎖的原理,分布式鎖也是一樣的,要實(shí)現(xiàn)它必須滿足:
互斥:任何時(shí)刻只能有一個(gè)客戶端對(duì)其加鎖;
避免死鎖:要充分考慮某客戶端在持有鎖的期間崩潰,也不能導(dǎo)致后續(xù)其他客戶端不能加鎖;
誰(shuí)加鎖誰(shuí)解鎖:加鎖和解鎖必須是同一個(gè)客戶端,否則容易出現(xiàn)A客戶端把B客戶端的鎖給解了,導(dǎo)致鎖機(jī)制失效。
示例實(shí)踐
我們僅以Redis實(shí)現(xiàn)分布式鎖為例來(lái)說(shuō)明分布式鎖的實(shí)現(xiàn)。以單機(jī)單機(jī)部署Redis的情況為例,如果有分布式Redis集群部署的情況,可以參考Redlock算法的實(shí)現(xiàn)。下面我們進(jìn)入Redis+Lua實(shí)現(xiàn)分布式鎖的實(shí)踐。
我們來(lái)看示例代碼。
加鎖
注意到代碼的每個(gè)細(xì)節(jié)了么?都是至關(guān)重要的。上面的set是封裝過(guò)的,那我們來(lái)簡(jiǎn)單說(shuō)明一下這個(gè)方法吧,該方法分別對(duì)應(yīng)了上面的鎖需要滿足的條件。比如,NX操作保證了鎖的互斥,設(shè)置過(guò)期時(shí)間避免了死鎖,唯一請(qǐng)求ID用來(lái)標(biāo)注客戶端,在解鎖的時(shí)候可以用來(lái)校驗(yàn)是不是同一個(gè)客戶端自己的鎖。
解鎖
解鎖這個(gè)動(dòng)作就有趣了,看似簡(jiǎn)單卻暗藏玄機(jī),也是很重要的環(huán)節(jié)。因?yàn)榻怄i存在一個(gè)判斷是都本客戶端的鎖的操作,之后才執(zhí)行解鎖。而這個(gè)if判斷在高并發(fā)的情況下我們不得不考慮操作的原子性,這其實(shí)和PHP等其他語(yǔ)言代碼考慮高并發(fā)的原理是大相徑庭(有興趣的看官也可以思考下,為什么有判斷就要保證原子性呢,有哪些可能出現(xiàn)問(wèn)題的場(chǎng)景)。那我們?nèi)绻WC操作的原子性呢?第一反應(yīng)是想到事務(wù)?我們這里借助Lua腳本來(lái)保證原子性,Redis的eval命令執(zhí)行Lua腳本保證原子性。
我們來(lái)看下示例代碼
我們同樣來(lái)說(shuō)明下面的解鎖代碼。其實(shí)很簡(jiǎn)單,就是執(zhí)行了一個(gè)Lua腳本,這個(gè)腳本實(shí)現(xiàn)了或者當(dāng)前鎖的值,即唯一請(qǐng)求ID值,判斷是否同一個(gè)客戶端的請(qǐng)求ID,如果是,則執(zhí)行Redis的del操作。
好了,關(guān)于Redis實(shí)現(xiàn)分布式的鎖例子就到這里了,這里只是簡(jiǎn)單的示例便于理解,實(shí)際生產(chǎn)將需要考慮更多的場(chǎng)景和因素,比如集群,Zookeeper方式實(shí)現(xiàn),時(shí)間和能力有限,這里就不展開(kāi)贅述。
-
死鎖
+關(guān)注
關(guān)注
0文章
25瀏覽量
8197 -
分布式
+關(guān)注
關(guān)注
1文章
993瀏覽量
75299 -
程序互斥
+關(guān)注
關(guān)注
0文章
3瀏覽量
6216
發(fā)布評(píng)論請(qǐng)先 登錄
Redis 分布式鎖的正確實(shí)現(xiàn)方式
為什么需要分布式鎖 基于Zookeeper鎖安全嗎
分布式鎖的設(shè)計(jì)與實(shí)現(xiàn)
深入理解redis分布式鎖

Redis實(shí)現(xiàn)分布式鎖的幾種方案
什么是分布式鎖 Redis的五種分布式鎖方案

tldb提供分布式鎖使用方法

評(píng)論