
之前用redis setnx實作分布式鎖的時候遇到一些問題,例如不是原子性等問題,看網上部落格文章都是建議去用lua腳本去保證原子性。
由于沒接觸過lua腳本,就去菜鳥教程看了相關文法了解了意思。寫了以下代碼。
import
相比 一開始寫的代碼,有幾處改動。
1、将一開始設定加鎖成功的代碼塊裡,做的rediskey逾時設定去掉了,因為沒保證加鎖的同時設定逾時時間,如果加鎖成功後線程挂掉,鎖沒有逾時時間,導緻無法釋放鎖。
2、将作為鎖的rediskey的值設定為随機數或者跟随時間戳變化的數,這樣做的目的是保證解鎖的線程與加鎖的線程一緻。
總結起來就是一個可靠的分布式鎖需要具備以下四個特征:
互斥性。在任意時刻,隻有一個用戶端能持有鎖。
不會發生死鎖。即使有一個用戶端在持有鎖的期間崩潰而沒有主動解鎖,也能保證後續其他用戶端能加鎖。
具有容錯性。隻要大部分的Redis節點正常運作,用戶端就可以加鎖和解鎖。
解鈴還須系鈴人。加鎖和解鎖必須是同一個用戶端,用戶端自己不能把别人加的鎖給解了。
回到代碼上的lua腳本。我寫了兩行代碼,一行加鎖的
if
一行解鎖的
if
一開始我隻是止步于這行代碼能運作成功就行,畢竟網上可以copy,但是網上文章繁多,代碼參差不齊,也不乏一些錯誤代碼。于是我不太相信,本着程式員對未知代碼就想debug的原則,我查閱了網上關于lua腳本的編輯器能否做debug用。
果然找到了專門的lua編輯器zbstudio ,我已經上傳到網盤,大家自取。
連結:https://pan.baidu.com/s/1A29q8qqQ-VFJA8RBjGNFgw
提取碼:9nkt
其中的exe檔案是安裝包,直接輕按兩下執行即可。在運作後,将redis.lua檔案放入安裝目錄下的packages目錄下然後重新打開zbstudio即可。
然後打開後就可以看到如下的界面。
點選紅色圈住的Redis進行設定。
接着我們運作一下上面的加鎖代碼。
把代碼中的KEYS[1],ARGV[1],EXPIRE替換為你在業務代碼裡的常量,快去試試吧。
其中KEYS[1]是redis的key,ARGV[1]為value,EXPIRE為key的失效時間(毫秒機關)
調試過程中的資訊如果出現
“ Detected Redis server v3, but need v3.2+ for the debugging to work.
Unknown SCRIPT subcommand or wrong # of args. ”
表明redis 版本該更新了。低版本還不支援debug。不過運作是正常的。
之前在公司看到同僚有用指令行去連接配接redis的,感覺操作不友善,網上找到一個不錯的redis用戶端,
下載下傳位址:
qishibo/AnotherRedisDesktopManagergithub.com
截個圖,界面上直覺顯示了redis server的很多資訊以及鍵值對資訊。