redis分佈式鎖設置的3種方式

setnx + lua

通過redis lua腳本,將設置值和設置超時時間在redis服務端一次執行。
eval script numkeys key [key …] arg [arg …]
其中script爲lua腳本,numkeys爲鍵個數

127.0.0.1:6379> eval "if redis.call('setnx', KEYS[1], KEYS[2]) == 1 then return redis.call('expire', KEYS[1], KEYS[3]) end" 3 name11 qdm 30
(integer) 1
127.0.0.1:6379> ttl name11
(integer) 28
127.0.0.1:6379> eval "if redis.call('setnx', KEYS[1], KEYS[2]) == 1 then return redis.call('expire', KEYS[1], KEYS[3]) end" 3 name11 qdm 30
(nil)
127.0.0.1:6379> ttl name11
(integer) 25

set key value [EX seconds] [PX milliseconds] [NX|XX]

EX / PX:鍵的過期時間
NX:只有鍵的key值不存在的時候才設置key的值
XX:只有鍵的key存在的時候纔會設置key的值

127.0.0.1:6379> set name22 qdm EX 30 XX
(nil)
127.0.0.1:6379> set name22 qdm EX 30 NX
OK
127.0.0.1:6379> ttl name22
(integer) 25
127.0.0.1:6379> set name22 qdm EX 30 NX
(nil)
127.0.0.1:6379> set name22 qdm EX 30 XX
OK
127.0.0.1:6379> ttl name22
(integer) 27
127.0.0.1:6379> del name22
(integer) 1
127.0.0.1:6379> ttl name22
(integer) -2
127.0.0.1:6379> set name22 qdm EX 30 NX
OK
127.0.0.1:6379> eval "if redis.call('get',KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end" 1 name22 qdm
(integer) 1
127.0.0.1:6379> ttl name22
(integer) -2

redlock

網上關於該實現很多。

幾種實現方式的缺點

前兩種只作用單節點(即使redis通過sentinel保證高可用,但是由於主從同步原因仍然可能發生丟失)。
redlock是依賴於時鐘的,使用時要求超時時間要遠小於鎖的失效時間。參見:https://martin.kleppmann.com/2016/02/08/how-to-do-distributed-locking.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章