redis实现分布式锁(乞丐版)
文章目錄
- redis分布式鎖
- 分布式鎖
- 加鎖
- 解鎖
redis分布式鎖
今天記錄一下redis實現分布式鎖,寫這個話題我猶豫了很久,因為這個實現雖然很容易,但是有很多細節需要注意,一不小心就死鎖,但是仔細一想好像也沒幾個人看我的文章,就當給自己做個筆記吧!大佬們要是發現那兒思路有問題,期待你能指出來哦,在生產環境下最好用redisson,別傻傻的自己實現了
在單機下我們的多線程爭搶資源是很好解決的,無非就是加鎖,Reentrantlock,synchronized等等都行,但是在多線程的情況下,他們已經不是同一個JVM了,他們是不可能在自己的JVM鎖到同一個對象的,如圖:
所以,在分布式系統中我們需要的是這樣一個架構:
這兒的中間件我們今天就是用的redis,后面可能會再寫一下zookeeper實現分布式鎖
我們只需要知道的幾個很簡單的redis命令:
set 示例: set name xiaoZ EX 5 NX 解釋: 設置name字段的值為xiaoZ,失效時間為5秒,如果不存在這個key的話
expire 示例: expire name 5 解釋: 設置name字段的超時時間為5秒
del 示例: del name 解釋: 刪除name字段
分布式鎖
假設現在兩臺機器一共8個線程都在爭搶鎖
加鎖
那么他們怎么才能算搶到鎖呢?
redis發揮作用了,set加上NX參數能保證只有一次set操作能成功,為什么呢?我們暫且可以將redis理解為單線程,所以進來的8個操作是排好隊的,聽大佬們說好像redis并不完全都是單線程,這兒等我了解后再記錄吧。(小本本記上)
set lock 只有自己知道的一個值,可以是隨機數 EX 5 NX
既然只有一個操作能成功的話,那不就不用擔心資源爭搶的問題了,不就實現了分布式加鎖了嗎?
網上很多方案是用setnx加expire,其實這兒會有一點問題,因為他不是原子性的,如果在setnx之后剛好宕機了,那么這個鎖就沒有失效時間了,造成死鎖,當然,這兒可以用lua腳本操作,lua腳本是具備原子性的
解鎖
解鎖直接使用del將lock這個鍵刪除不就解鎖了嗎,不過要注意的是,我們需要判斷一下這個鎖是不是自己的,怎么判度就是去對比value,這個value只有自己知道,如果一樣就刪除,那么需要先判斷一下,那么又出現了原子問題,這兒我們可以使用lua腳本實現,因為之前說過lua腳本是具備原子性的
if redis.call('get',KEYS[1]) == ARGV[1] then return redis.call('del',KEYS[1]) elsereturn 0 end總結
以上是生活随笔為你收集整理的redis实现分布式锁(乞丐版)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python-指数分布介绍(scipy.
- 下一篇: 面向对象的六大原则