setnx作用是什麼 redis
Redis有一系列的命令,特點是以NX結尾,NX是Not eXists的縮寫,如SETNX命令就應該理解為:SET if Not eXists。這系列的命令非常有用,這裡講使用SETNX來實現分散式鎖。
解決死鎖
上面的鎖定邏輯有一個問題:如果一個持有鎖的客戶端失敗或崩潰了不能釋放鎖,該怎麼解決?我們可以通過鎖的鍵對應的時間戳來判斷這種情況是否發生了,如果當前的時間已經大於lock.foo的值,說明該鎖已失效,可以被重新使用。
發生這種情況時,可不能簡單的通過DEL來刪除鎖,然後再SETNX一次,當多個客戶端檢測到鎖超時後都會嘗試去釋放它,這裡就可能出現一個競態條件,讓我們模擬一下這個場景:
C0操作超時了,但它還持有著鎖,C1和C2讀取lock.foo檢查時間戳,先後發現超時了。
C1 傳送DEL lock.foo
C1 傳送SETNX lock.foo 並且成功了。
C2 傳送DEL lock.foo
C2 傳送SETNX lock.foo 並且成功了。
這樣一來,C1,C2都拿到了鎖!問題大了!
幸好這種問題是可以避免的,讓我們來看看C3這個客戶端是怎樣做的:
C3傳送SETNX lock.foo 想要獲得鎖,由於C0還持有鎖,所以Redis返回給C3一個0
C3傳送GET lock.foo 以檢查鎖是否超時了,如果沒超時,則等待或重試。
反之,如果已超時,C3通過下面的操作來嘗試獲得鎖:
GETSET lock.foo <current Unix time + lock timeout + 1>
通過GETSET,C3拿到的時間戳如果仍然是超時的,那就說明,C3如願以償拿到鎖了。
如果在C3之前,有個叫C4的客戶端比C3快一步執行了上面的操作,那麼C3拿到的時間戳是個未超時的值,這時,C3沒有如期獲得鎖,需要再次等待或重試。留意一下,儘管C3沒拿到鎖,但它改寫了C4設定的鎖的超時值,不過這一點非常微小的誤差帶來的影響可以忽略不計。
注意:為了讓分散式鎖的演算法更穩鍵些,持有鎖的客戶端在解鎖之前應該再檢查一次自己的鎖是否已經超時,再去做DEL操作,因為可能客戶端因為某個耗時的操作而掛起,操作完的時候鎖因為超時已經被別人獲得,這時就不必解鎖了。
示例虛擬碼
根據上面的程式碼,我寫了一小段Fake程式碼來描述使用分散式鎖的全過程:
# get lock
lock = 0
while lock != 1:
timestamp = current Unix time + lock timeout + 1
lock = SETNX lock.foo timestamp
if lock == 1 or (now() > (GET lock.foo) and now() > (GETSET lock.foo timestamp)):
break;
else:
sleep(10ms)
# do your job
do_job()
# release
if now() < GET lock.foo:
DEL lock.foo
是的,要想這段邏輯可以重用,使用python的你馬上就想到了Decorator,而用Java的你是不是也想到了那誰?AOP + annotation?行,怎樣舒服怎樣用吧,別重複程式碼就行。
http://redis.io/commands/setnx
http://my.oschina.net/u/1995545/blog/366381
內容均為作者獨立觀點,不代表八零IT人立場,如涉及侵權,請及時告知。
相關文章
- redis分散式鎖-SETNX實現Redis分散式
- python反向引用是什麼?Python
- python的引用是什麼Python
- 精益IT的作用是什麼?
- text/plain的作用是什麼AI
- jQuey return false作用是什麼False
- MySql delimiter的作用是什麼MySqlMIT
- kubelet的功能、作用是什麼
- web裡什麼是Math函式,作用是什麼Web函式
- 什麼是CDN?CDN的原理和作用是什麼?
- Linux中gpgcheck是什麼意思?作用是什麼?LinuxGC
- 什麼是@Component,@Component的作用是什麼
- http代理IP的作用是什麼?HTTP
- jQuery.fn的作用是什麼jQuery
- css hack \9的作用是什麼CSS
- MySql中delimiter的作用是什麼?MySqlMIT
- Redis 事務不解決 SETNX DECR 過期問題Redis
- 什麼是訊息中介軟體?主要作用是什麼?
- 資料庫審計是什麼意思?作用是什麼?資料庫
- 大資料的作用是幹什麼大資料
- Laravel模型屬性$dates作用是什麼?Laravel模型
- __name__ == "__main__"的作用是什麼?AI
- __name__ == “__main__”的作用是什麼?AI
- 薪酬管理系統的作用是什麼?
- js中逗號(,)的作用是什麼JS
- javascript:void(0)的作用是什麼JavaScript
- 什麼是智慧網路卡?智慧網路卡的作用是什麼?
- 快應用是什麼軟體?快應用有什麼用?
- Linux中opt是什麼意思?其主要作用是什麼?Linux
- Redis 使用 Lua 指令碼替代 SETNX / DECR 保證原子性Redis指令碼
- 使用redis中setnx防止併發二次寫入Redis
- Linux系統中掛載是什麼意思?作用是什麼?Linux
- AI開放平臺的作用是什麼?AI
- 【乾貨】Linux中presto作用是什麼?LinuxREST
- Proposer-Builder Separation (PBS) 的作用是什麼?UI
- dis ip int brief命令的作用是什麼?
- that=this這樣的程式碼的作用是什麼
- javascript兩個歎號!!的作用是什麼JavaScript