分布式鎖解決因為刪鎖而產生的兩種問題

2021-10-12 01:56:02 字數 2793 閱讀 1688

設定鎖過期時間,訪問資料庫後刪除鎖。涉及的兩種問題都是毫秒級別的問題,為了減輕伺服器的壓力,一般在大廠裡要完善的**。

而小公司裡,則不需要這麼麻煩,不設計刪除鎖,直接等待過期時間過去自動刪除鎖。這樣就省去了因為刪除鎖產生的一系列問題。

分布式鎖的兩種問題:

第一種問題:鎖過期,刪除鎖,把別人的刪了

第1條執行緒拿鎖進去訪問資料庫,突然該執行緒發生了意外,等待時間較長,直到過期時間到了(鎖釋放,第2條執行緒拿鎖進入訪問)!突然:第1條執行緒復活,訪問資料庫出來,刪除鎖(此時把第2條執行緒的鎖給刪除了)

請設計方案解決這個問題,怎麼防止誤刪別人的鎖?

uuid 的概念

uuid(universally unique identifier):通用唯一識別碼,是一種軟體建構的標準。

uuid 目的是讓分布式系統中的所有元素,都能有唯一的辨識資訊,而不需要通過**控制端來做辨識資訊的指定。

uuid是指在一台機器上生成的數字,它保證對在同一時空中的所有機器都是唯一的。

雖然設定這把鎖key是唯一的(sku:skuid:lock),但是可以設定value不唯一:

採用uuid.randomuuid().tostring()生成隨機數。

每設定一把鎖都是不同的value,根據不同的value識別唯一的鎖

set一把鎖,再get這一把鎖,就可以獲得value值(相當於這把鎖的密碼,用uuid隨機生成獨一無二的密碼)

答:第1條執行緒如果要刪除鎖,get一下key的鎖(第2條執行緒設定的鎖),雖然它是同乙個key,但是value卻是唯一的。

第1條執行緒get到的value值,和開頭設定的value值不同,不給刪除!!!

這樣就實現了避免誤刪別人的鎖了。

;//每設定一把鎖都是不同的value,根據不同的value識別唯一的鎖

string ok = jedis.

set(

"sku:"

+ skuid +

":lock"

, token,

"nx"

,"px",10

*1000);

拿鎖訪問資料庫,省略。。。

string locktoken = jedis.

get(

"sku:"

+ skuid +

":lock");

//get鎖的value值,自己設定的則刪除。get別人鎖的value值,則不刪除!

if(stringutils.

isnotblank

(locktoken)

&&locktoken.

equals

(token)

)第二種問題:get到key鎖相等uuid的value(允許刪鎖),鎖過期,刪除鎖,把別人的刪了。在乙個問題的基礎上,使用uuid雖然可以解決問題,但是在刪除鎖的時候!假設第1條執行緒get到value值是自己的(可以刪除鎖),但正在做判斷if的時候,鎖剛好過期,鎖釋放!鎖一釋放,第2條執行緒就拿到鎖了。

這時第1條執行緒做完if判斷了,進入刪除鎖,又把第2條執行緒的鎖刪了!!!

怎樣解決這個問題?

使用lua指令碼,保證執行**段的原子性,get到鎖相等的value就刪除,就是乙個殺手,逮到就刪,否則不刪。

使用lua指令碼替代第乙個問題刪除鎖的三個步驟(get查詢,if判斷,del刪除)

是第乙個問題的高階版本

string token = uuid.

randomuuid()

.tostring()

;//每設定一把鎖都是不同的value,根據不同的value識別唯一的鎖

string ok = jedis.

set(

"sku:"

+ skuid +

":lock"

, token,

"nx"

,"px",10

*1000);

拿鎖訪問資料庫,省略。。。

//使用lua指令碼刪除鎖

//keys[1]對應第乙個singletonlist查鎖的value,ar**[1]對應第二個singletonlist的token-uuid值。

//如果value==token,則刪除!否則不刪!

string script =

"if redis.call('get', keys[1]) == ar**[1] then return redis.call('del', keys[1]) else return 0 end"

;//訪問資料庫結束後,刪除鎖。下乙個使用者繼續拿鎖訪問!

這裡就不測試了,這裡取最優lua指令碼刪除鎖的第二種方法寫進**

分布式鎖的鎖優化

在去除原有synchronized單機鎖後,在關鍵步驟新增分布式鎖來對具體業務進行鎖定,然而由於鎖定範圍大,導致鎖競爭增加,不斷發生鎖等待,如果不進行優化,可能會讓執行緒佇列增大甚至阻塞,而且在等待時長超過設定的閾值時,執行緒將超時返回。在此,初步對鎖進行優化,如何理解分布式鎖與單機鎖的應用範圍和實...

分布式鎖解決方案

分布式鎖三種實現方式 1.基於資料庫實現分布式鎖 2.基於快取 redis等 實現分布式鎖 3.基於zookeeper實現分布式鎖 1.悲觀鎖 利用select where for update 排他鎖 注意 其他附加功能與實現一基本一致,這裡需要注意的是 where name lock name欄...

分布式環境下的解決方案 分布式鎖

分布式鎖,也就是在多程序情況下的鎖。需要有儲存鎖的空間,並且鎖的空間是可以訪問到的。鎖需要被唯一標識。鎖要有至少兩種狀態。儲存空間 鎖是乙個抽象的概念,鎖的實現,需要依存於乙個可以儲存鎖的空間。在多執行緒中是記憶體,在多程序中是記憶體或者磁碟。更重要的是,這個空間是可以被訪問到的。多執行緒中,不同的...