原理很簡單,set 壹個 鎖-key,如果成功則說明加鎖成功,反之則失敗。
為了確保分布式鎖可用,我們至少要確保鎖的實現同時滿足以下幾個條件:
基於以上條件,采用set擴展參數,保證原子性操作: SET lock-key "lock-client" EX 10086 NX
lock-key "lock-client" 指定 加鎖client,解鎖時用於判斷。
EX 10010 指定過期時間
NX 只在鍵不存在時,才對鍵進行設置操作。效果等同於 SETNX 命令。
只不過早期版本redis不支持set的擴展參數,這就需要用到 lua 腳本了 。
加鎖可以在高版本借助set命令實現原子操作,但解鎖就不可以了,依然得用到lua腳本。
Redis在2.6版本推出了 lua 腳本功能,允許開發者使用Lua語言編寫腳本傳到Redis中執行。使用腳本的好處如下:
需要在獲得 lock-key 後判斷加鎖對象是否為當前client,是,則解鎖。Lua 腳本如下:
if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end
執行方式:eval;
eval 參數列表: eval lua-script key-num [key1 key2 key3 ....] [value1 value2 value3 ....] ,參數解析:
eval執行示例: eval "redis.call('set',KEYS[1],ARGV[1])" 1 lua-key lua-val ;
完整解鎖執行腳本:
eval "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end" 1 lock-key client-val
----------End----------