使用Redis实现基本加锁操作的命令及参数含义
- SETNX命令
- 命令:
SETNX key value
- 含义:
SETNX
是 SET if Not eXists
的缩写。如果 key
不存在,将 key
设置为 value
并返回 1
,表示加锁成功;如果 key
已经存在,不做任何操作并返回 0
,表示加锁失败。这里 key
通常作为锁的标识,例如可以是业务相关的唯一标识(如订单号等),value
可以是一个唯一值(如客户端生成的UUID),用于后续解锁时验证是否是当前加锁的客户端。
- SET命令(使用NX选项)
- 命令:
SET key value NX
- 含义:这是
SET
命令的一种变体,NX
选项表示只有在 key
不存在时才设置 key
的值。与 SETNX
命令类似,如果 key
不存在,将 key
设置为 value
并返回 OK
,加锁成功;如果 key
存在,则不做任何操作并返回 nil
,加锁失败。key
和 value
的含义与 SETNX
中的类似。
处理加锁失败的情况
- 重试机制
- 说明:加锁失败后,客户端可以在一定时间间隔后重试加锁操作。例如使用指数退避算法,每次重试的间隔时间呈指数增长(如100ms、200ms、400ms等),避免短时间内大量无效重试对系统造成压力。代码示例(以Python为例):
import redis
import time
r = redis.Redis(host='localhost', port=6379, db = 0)
lock_key = 'order_lock'
lock_value = 'unique_value'
retry_count = 0
while True:
result = r.set(lock_key, lock_value, nx = True)
if result:
# 加锁成功,执行相关业务逻辑
try:
# 业务代码
pass
finally:
r.delete(lock_key) # 解锁
break
else:
# 加锁失败,重试
sleep_time = 100 * (2 ** retry_count) / 1000 # 指数退避时间
time.sleep(sleep_time)
retry_count += 1
- 排队处理
- 说明:可以使用Redis的列表(
LIST
)数据结构来实现排队机制。加锁失败的客户端将自己的请求信息(如任务ID、客户端标识等)添加到一个列表中。当持有锁的客户端完成业务操作并解锁后,从列表中取出下一个请求,通知对应的客户端进行加锁尝试。例如,使用 RPUSH
命令将请求添加到列表尾部,使用 LPOP
命令从列表头部取出请求。
- 放弃操作
- 说明:对于一些对并发要求不是特别高或者加锁失败影响较小的业务场景,可以直接放弃当前操作,并向用户返回相关提示信息,如“系统繁忙,请稍后重试”等。