redis分布式鎖--001(組合命令的演變過程)

分布式鎖

分布式鎖本質上要實現的目標就是在 Redis 里面占一個“茅坑”,當別的進程也要來占

時,發現已經有人蹲在那里了,就只好放棄或者稍后再試。
占坑一般是使用 setnx(set if not exists) 指令,只允許被一個客戶端占坑。先來先占, 用
完了,再調用 del 指令釋放茅坑。



但是有個問題,如果邏輯執行到中間出現異常了,可能會導致 del 指令沒有被調用,這樣
就會陷入死鎖,鎖永遠得不到釋放。
于是我們在拿到鎖之后,再給鎖加上一個過期時間,比如 5s,這樣即使中間出現異常也
可以保證 5 秒之后鎖會自動釋放。



但是以上邏輯還有問題。如果在 setnx 和 expire 之間服務器進程突然掛掉了,可能是因
為機器掉電或者是被人為殺掉的,就會導致 expire 得不到執行,也會造成死鎖。
這種問題的根源就在于 setnx 和 expire 是兩條指令而不是原子指令。如果這兩條指令可
以一起執行就不會出現問題。也許你會想到用 Redis 事務來解決。但是這里不行,因為 expire

是依賴于 setnx 的執行結果的,如果 setnx 沒搶到鎖,expire 是不應該執行的。事務里沒有 if-
else 分支邏輯,事務的特點是一口氣執行,要么全部執行要么一個都不執行。
為了解決這個疑難,Redis 開源社區涌現了一堆分布式鎖的 library,專門用來解決這個問
題。實現方法極為復雜,小白用戶一般要費很大的精力才可以搞懂。如果你需要使用分布式鎖,意味著你不能僅僅使用 Jedis 或者 redis-py 就行了,還得引入分布式鎖的 library。



為了治理這個亂象,Redis 2.8 版本中作者加入了 set 指令的擴展參數,使得 setnx 和
expire 指令可以一起執行,徹底解決了分布式鎖的亂象。從此以后所有的第三方分布式鎖
library 可以休息了。 > set lock:codehole true ex 5 nx OK ... do something critical ... > del
lock:codehole 上面這個指令就是 setnx 和 expire 組合在一起的原子指令,它就是分布式鎖的
奧義所在
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容