溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

zookeeper(3)分布式鎖

發(fā)布時(shí)間:2020-08-06 13:53:14 來源:網(wǎng)絡(luò) 閱讀:386 作者:shayang88 欄目:編程語言

在一個(gè)分布式系統(tǒng)中,如何保證一個(gè)操作,同一時(shí)間只有一個(gè)線程可以執(zhí)行,這就是分布式鎖的使用場(chǎng)景,同一時(shí)間,只有一個(gè)線程可以獲得鎖的使用權(quán)。

如何實(shí)現(xiàn)一個(gè)分布式鎖?

實(shí)現(xiàn)一個(gè)分布式鎖,可以有以下3種方法。

一、基于數(shù)據(jù)庫實(shí)現(xiàn)分布式鎖。

1、在MySQL中,使用悲觀鎖"select from t where id = for update"可以對(duì)行數(shù)據(jù)進(jìn)行加鎖,來實(shí)現(xiàn)分布式鎖。
2、同一個(gè)時(shí)間內(nèi),只會(huì)有一個(gè)線程加鎖成功,其他線程必須等待。
3、數(shù)據(jù)庫要保證是全局的,每一把鎖所對(duì)應(yīng)的行數(shù)據(jù)也是唯一的。

優(yōu)點(diǎn):

1、實(shí)現(xiàn)簡(jiǎn)單,方便。

缺點(diǎn):

1、基于數(shù)據(jù)庫的悲觀鎖,性能比較差。
2、等待中的線程是自旋的或者等待狀態(tài),需要等待持有鎖的線程處理完,多個(gè)線程再一起去競(jìng)爭(zhēng)同一把鎖。
3、異常無法處理,當(dāng)持有鎖的線程還沒有釋放鎖,意外退出,鎖資源將無法釋放,應(yīng)用程序?qū)o法繼續(xù)進(jìn)行。

二、基于redis實(shí)現(xiàn)的分布式鎖。

1、使用redis的setnx命令,可以模擬分布式鎖,setnx保證操作一個(gè)key值,如果沒有則返回true,如果存在則返回false。
2、為了解決程序意外退出導(dǎo)致無法釋放鎖資源,需要給key增加一個(gè)超時(shí)時(shí)間。
3、redis提供了帶參數(shù)的命令,可以保證設(shè)置key值和設(shè)置超時(shí)時(shí)間這2個(gè)操作的原子性

SET key value [EX seconds] [PX milliseconds] [NX|XX]

4、假如有如下情況:

A獲取了鎖,設(shè)置了超時(shí)時(shí)間為10秒,但是A執(zhí)行了15秒,在10秒的時(shí)候鎖失效了。
B在11秒的時(shí)候獲取了鎖,執(zhí)行了5秒,那么A在15秒的時(shí)候會(huì)誤刪掉B的鎖。

為了解決以上問題,每個(gè)加鎖的線程都需要設(shè)置自己的value值,當(dāng)刪除的時(shí)候也要校驗(yàn)是自己的鎖,才可以刪除。

優(yōu)點(diǎn):

1、實(shí)現(xiàn)簡(jiǎn)單,方便。
2、基于redis的高性能,效率高。

缺點(diǎn):

1、無法解決超時(shí)鎖失效問題,邏輯處理的時(shí)間超過了設(shè)置的超時(shí)時(shí)間,那么這個(gè)時(shí)候就會(huì)導(dǎo)致,另一個(gè)也可以拿到鎖繼續(xù)執(zhí)行。

為了解決這個(gè)問題,一般的方法是啟動(dòng)一個(gè)守護(hù)線程,時(shí)刻監(jiān)控失效時(shí)間,當(dāng)鎖時(shí)間超過一定的執(zhí)行時(shí)間比例之后,自動(dòng)續(xù)約一定的時(shí)間,當(dāng)然這個(gè)總時(shí)間是有最大閾值限制的。

2、等待中的線程是自旋的后者等待狀態(tài),需要等待持有鎖的線程處理完,多個(gè)線程再一起去競(jìng)爭(zhēng)同一把鎖。

三、zookeeper實(shí)現(xiàn)分布式鎖

方式1:悲觀鎖

1、使用臨時(shí)節(jié)點(diǎn)實(shí)現(xiàn)分布式鎖,第一個(gè)創(chuàng)建臨時(shí)節(jié)點(diǎn)成功的線程,獲取鎖成功。
2、其他創(chuàng)建臨時(shí)節(jié)點(diǎn)的線程會(huì)失敗,那么監(jiān)聽鎖的臨時(shí)節(jié)點(diǎn)。
3、當(dāng)鎖釋放的時(shí)候,刪除臨時(shí)節(jié)點(diǎn),會(huì)通知到監(jiān)聽的線程,收到通知的線程繼續(xù)嘗試創(chuàng)建臨時(shí)鎖節(jié)點(diǎn),誰創(chuàng)建成功誰獲得鎖。

優(yōu)點(diǎn):

解決了鎖失效問題,通知機(jī)制可以完美解決,即使創(chuàng)建臨時(shí)節(jié)點(diǎn)的線程掛掉,臨時(shí)節(jié)點(diǎn)會(huì)自動(dòng)刪除。

缺點(diǎn):

1、當(dāng)有大量線程,等待鎖資源的時(shí)候,鎖資源釋放會(huì)涉及到大量的通知,并且大量的線程需要一起競(jìng)爭(zhēng)鎖資源。

方式2:樂觀鎖

1、在一個(gè)目錄下,各個(gè)線程創(chuàng)建順序的臨時(shí)節(jié)點(diǎn),節(jié)點(diǎn)編號(hào)1、2、3、4、5等。
2、目錄下創(chuàng)建的節(jié)點(diǎn)最小的線程獲取鎖。
3、等待鎖資源的線程,不再一起全部監(jiān)聽鎖節(jié)點(diǎn),而是只監(jiān)聽比自己小的上一個(gè)節(jié)點(diǎn)。
4、當(dāng)監(jiān)聽的比自己小的鎖節(jié)點(diǎn)被刪除后,繼續(xù)改為監(jiān)聽上一個(gè)比自己小的節(jié)點(diǎn)。
4、當(dāng)鎖釋放的時(shí)候,只需要通知監(jiān)聽鎖節(jié)點(diǎn)的一個(gè)獲幾個(gè)線程,避免了大量的通知。

zookeeper實(shí)現(xiàn)的樂觀鎖,是比較合理的分布式鎖方式,感興趣的朋友可以用代碼實(shí)現(xiàn)一下。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI