Redis分布式非公平鎖詳解

2021-09-25 22:56:31 字數 2773 閱讀 3501

大家應該都知道redis做分布式鎖無非就是incr命令或者是setnx命令,這裡我們採用setnx命令。

操作:setnx key 如果操作成功則代表拿到鎖,如果沒有操作成功則代表沒有拿到鎖。

缺點:如果這個人拿到鎖後宕機了怎麼辦,那麼這個鎖就再也不能釋放了。

改進:給這個鎖增加乙個過期時間,這樣如果有效期過了,那麼這個鎖就會自動釋放了。

通過上面所說我們應該對redis分布式進行改進。

操作: 使用setnx 命令,之後,在expireat key 30000 這條命令設定key的有效期為30秒。

這裡我們可能會發現,如果要是剛setnx結束之後,要是宕機了。怎麼辦?那麼我們為了保證原子性,所以jedis提供了乙個原子操作,set(key,value,nx,30,時間單位)這樣便解決了。

缺點:如果這個鎖的時間不夠用怎麼辦,那麼就會導致這個功能鎖不住。假設:a拿到鎖了,但是a還沒有執行結束,b又拿到鎖了,那麼a執行結束的時候是不是會把b的這個鎖給刪除掉。這樣就導致了鎖不住的效果。

改進:我們可以學習樂觀所,給鎖的value值是乙個唯一的編號,或者版本號,我們每次對鎖進行操作的時候,就會去驗證這個版本號,還是不是自己的版本號。如果不是了就不允許操作了。

通過上面的總結這第三版想必也很簡單了。知識多了乙個唯一值而已。但是加了唯一值還是改變不了鎖不住的結果,只是解決了幫其他的執行緒解鎖的問題,那麼要怎麼樣才能鎖得住呢?當時我想到的是給他 時間久一點,後來發現其實再久,也一樣會出現鎖不住的時候,而且太久了如果宕機了,就會有很長時間機器無法工作,很容易造成執行緒堆積。

由上面我們發現一般簡單實用redis做鎖其實是有很多漏洞和bug的,但是有沒有能夠解決這些的呢?當然是有的。

模仿aqs鎖, lock方法執行完之後,執行下面**是被鎖的,unlock執行完,釋放鎖。其他執行緒等待,而不是直接返回錯誤結果。

最終版還是打算先上**再說,為了方便我把所有的實現都寫在了乙個類裡面。

@autowired

private redistemplate redistemplate;

@autowired

private redisutils redisutils;

@autowired

(required =

false

)private threadpooltaskscheduler threadpooltaskscheduler;

public

final string lock_prefix =

"redis_lock"

;private

final long lock_expire =30*

1000l;

private

final long over_time =

10l;

private map

?>

> futuremap =

newconcurrenthashmap

<

>()

;private jedis jedis;

public

lock()

private reentrantlock reentrantlock;

/** * 給執行緒枷鎖

** @param key

*/public

void

lock

(string key)},

newtrigger()

});return;}

}}/** * setnx

** @param key

* @return

*/public

boolean

setlock

(string key)

else}}

return

false;}

});}

/** * 刪除鎖

** @param key

*/public

void

unlock

(string key)

}/**

* 判斷key是否存在

** @param key 鍵

* @return true 存在 false不存在

*/public

boolean

haskey

(string key)

catch

(exception e)

}public set

scan

(string key)

else

}return keys;})

;}

分析:

判斷是否獲取到鎖,獲取到鎖,繼續執行,沒有獲取到鎖,自旋繼續獲取。

獲取到鎖後排程乙個任務。每10秒執行一次,並且如果發現所沒有釋放延長10秒。

釋放鎖,刪除掉redis中的key,並結束掉對應的鎖的任務。

加鎖執行原理:

解鎖操作原理:

解鎖操作就比較簡單了。但是得為了不出必要的麻煩,最好是給停止鎖延時任務,和刪除所 這兩部新增程序鎖,可以使用synchronized,也可以使用aqs lock鎖。

這裡redis非公平鎖詳解算是結束了,後期可能會更新使用redis,實現公平鎖,謝謝大家的支援,如果有需要的小夥伴可以直接拿走,希望能給大家帶來幫助。

Redis分布式非公平鎖的使用

目錄 看了很多部落格,和資料,這裡只針對redis做分布式鎖做一下深入 希望對你們有obwmx幫助。網上提供了很多分布式鎖的操作,這裡逐一舉例然後評論優缺點及改進方案,希望這樣子能讓當家更好的理解redis分布式鎖。大家應該都知道redis做分布式鎖無非就是incr命令或者是setnx命令,這裡我們...

Redis分布式鎖詳解

在網際網路分布式服務部署中,通常會遇到多個程序操作同乙個資源的情況,例如秒殺等,此文章主要介紹使用redis實現分布式鎖。redis為單程序單執行緒模式,採用佇列模式將併發訪問變為序列訪問。通常使用setnx 即set not exiest 來實現鎖,以下通過循序漸進的方式引入最終實現。方案一1.c...

redis實現分布式鎖詳解

解決問題 應對高併發業務場景 為什麼可以實現?首先redis是單執行緒的,這裡的單執行緒指的是網路請求模組使用了乙個執行緒 所以不需考慮併發安全性 即乙個執行緒處理所有網路請求,其他模組仍用了多個執行緒。實現原理 伺服器一的請求會先獲取到鎖,接下來如果來相同的請求,此時會返回獲取鎖失敗的狀態。直至本...