Redis分布式鎖的簡單實現 set命令及引數

2021-10-02 19:50:01 字數 3501 閱讀 3632

摘自:

set key value [ex seconds] [px milliseconds] [nx|xx]

如果 key 已經持有其他值, set 就覆寫舊值,無視型別。

對於某個原本帶有生存時間(ttl)的鍵來說, 當 set

命令成功在這個鍵上執行時, 這個鍵原有的 ttl 將被清除。

例:

# 對不存在的鍵進行設定

redis 127.0.0.1:6379> set key "value"

okredis 127.0.0.1:6379> get key

"value"

# 對已存在的鍵進行設定

redis 127.0.0.1:6379> set key "new-value"

okredis 127.0.0.1:6379> get key

"new-value"

# 使用 ex 選項

redis 127.0.0.1:6379> set key-with-expire-time "hello" ex 10086

okredis 127.0.0.1:6379> get key-with-expire-time

"hello"

redis 127.0.0.1:6379> ttl key-with-expire-time

(integer) 10069

# 使用 px 選項

redis 127.0.0.1:6379> set key-with-pexpire-time "moto" px 123321

okredis 127.0.0.1:6379> get key-with-pexpire-time

"moto"

redis 127.0.0.1:6379> pttl key-with-pexpire-time

(integer) 111939

# 使用 nx 選項

redis 127.0.0.1:6379> set not-exists-key "value" nx

ok # 鍵不存在,設定成功

redis 127.0.0.1:6379> get not-exists-key

"value"

redis 127.0.0.1:6379> set not-exists-key "new-value" nx

(nil) # 鍵已經存在,設定失敗

redis 127.0.0.1:6379> get not-exists-key

"value" # 維持原值不變

# 使用 xx 選項

redis 127.0.0.1:6379> exists exists-key

(integer) 0

redis 127.0.0.1:6379> set exists-key "value" xx

(nil) # 因為鍵不存在,設定失敗

redis 127.0.0.1:6379> set exists-key "value"

ok # 先給鍵設定乙個值

redis 127.0.0.1:6379> set exists-key "new-value" xx

ok # 設定新值成功

redis 127.0.0.1:6379> get exists-key

"new-value"

# nx 或 xx 可以和 ex 或者 px 組合使用

redis 127.0.0.1:6379> set key-with-expire-and-nx "hello" ex 10086 nx

okredis 127.0.0.1:6379> get key-with-expire-and-nx

"hello"

redis 127.0.0.1:6379> ttl key-with-expire-and-nx

(integer) 10063

redis 127.0.0.1:6379> set key-with-pexpire-and-xx "old value"

okredis 127.0.0.1:6379> set key-with-pexpire-and-xx "new value" px 123321

okredis 127.0.0.1:6379> get key-with-pexpire-and-xx

"new value"

redis 127.0.0.1:6379> pttl key-with-pexpire-and-xx

(integer) 112999

# ex 和 px 可以同時出現,但後面給出的選項會覆蓋前面給出的選項

redis 127.0.0.1:6379> set key "value" ex 1000 px 5000000

okredis 127.0.0.1:6379> ttl key

(integer) 4993 # 這是 px 引數設定的值

redis 127.0.0.1:6379> set another-key "value" px 5000000 ex 1000

okredis 127.0.0.1:6379> ttl another-key

(integer) 997 # 這是 ex 引數設定的值

命令 set resource-name anystringnxex max-lock-time 是一種在 redis 中實現鎖的簡單方法。

執行set命令,如果伺服器返回 ok ,那麼這個客戶端獲得鎖。 如果伺服器返回 nil ,那麼客戶端獲取鎖失敗,可以在稍後再重試。

設定的過期時間到達之後,鎖將自動釋放。

為了識別鎖的持有者,可以設定乙個不可猜測(non-guessable)的長隨機字串或直接使用uuid,作為口令(token)。

釋放時,使用lua 指令碼,這個指令碼只在客戶端傳入的值和鍵的口令串相匹配時,才對鍵進行刪除。保持原子性。

指令碼示例:

if redis.call("get",keys[1]) == ar**[1]

then

return redis.call("del",keys[1])

else

return 0

end

這個指令碼可以通過 eval ...script... 1 resource-name token-value 命令來呼叫。

互斥性:分布式鎖需要保證在不同節點的不同執行緒的互斥。這是最根本的。

可重入性:同乙個節點上的同乙個執行緒如果獲取了鎖之後也可以再次獲取這個鎖。

鎖超時:和本地鎖一樣支援鎖超時,防止死鎖。

高可用:加鎖和解鎖需要高效,同時也需要保證高可用防止分布式鎖失效,可以增加降級。

他還有下面的兩條feature:

支援阻塞和非阻塞:和 reentrantlock 一樣支援 lock 和 trylock 以及 trylock(long timeout)。

支援公平鎖和非公平鎖(可選):公平鎖的意思是按照請求加鎖的順序獲得鎖,非公平鎖就相反是無序的。這個一般來說實現的比較少。

更多見:

Redis分布式鎖簡單實現

偽 下訂單 1 查庫存 getstock 2 判斷庫存 stock 0下單 3 下單 addorder 4 減庫存 public class redisutils setnx param key param value param seconds 過期時間,單位秒 return public sta...

簡單聊聊分布式鎖 Redis分布式鎖

單機redis分布式鎖 單機redis分布式鎖 首先咱們先聊聊單機的redis分布式鎖 第乙個最普通的實現方式,就是在 redis 裡使用 setnx 命令建立乙個 key,這樣就算加鎖。set resource name my random value nx px 30000執行這個命令就 ok。...

分布式鎖 使用Redis實現分布式鎖

關於分布式鎖的實現,我的前一篇文章講解了如何使用zookeeper實現分布式鎖。關於分布式鎖的背景此處不再做贅述,我們直接討論下如何使用redis實現分布式鎖。關於redis,筆主不打算做長篇大論的介紹,只介紹下redis優秀的特性。支援豐富的資料型別,如string list map set zs...