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