基于 Redis 实现分布式锁

布式锁的含义
分布式锁是一种用于在分布式系统中控制多个节点对共享资源进行互斥访问的机制。它确保在同一时刻只有一个客户端能够获取锁并执行对共享资源的操作,从而避免并发问题如数据不一致、重复处理等。

实现分布式锁的方式
实现分布式锁有多种方式,常见的包括基于数据库、Redis、Zookeeper 等中间件。本文介绍以Redis的方式实现。

Redis 实现分布式锁
Redis 是一种高性能的键值存储系统,适合用来实现分布式锁。常见的实现方式是使用 SET 命令及其扩展选项。

加锁:

  • 使用 SET key value NX PX timeout 命令尝试设置一个键,并且只有当键不存在时(NX)才设置成功。
  • PX timeout 表示设置键的过期时间(毫秒),防止死锁(即客户端崩溃后锁未被释放)。
public boolean lock(String lockKey, String requestId, int expireTime) {
    String result = jedis.set(lockKey, requestId, "NX", "PX", expireTime);
    return "OK".equals(result);
}

解锁:

  • 使用 Lua 脚本来保证解锁操作的原子性,只有当前持有锁的客户端才能删除锁。
public boolean unlock(String lockKey, String requestId) {
    String luaScript =
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "return redis.call('del', KEYS[1]) " +
        "else return 0 end";
    Object result = jedis.eval(luaScript, Collections.singletonList(lockKey), Collections.singletonList(requestId));
    return "1".equals(result.toString());
}

Lua脚本解释:

命令:
redis.call(‘get’, KEYS[1]):表示执行reids命令 get KEYS[1] 来获取该键所对应的值
KEYS[1]:实际上是指从 jedis.eval()方法传入的第2个参数中获取键的值,[1]代表list中第一个元素,由于使用Collections.singletonList(lockKey)创建的list只有一个元素,即传入的键值。若lockKey值为"abc"最终执行的reids命令就是 get abc,获取abc键所对应的值。
redis.call(‘get’, KEYS[1]) == ARGV[1]:若获取到的值与传入的值相等则删除键,若比较不相等则返回0。其中ARGV[1]代表,从jedis.eval()方法传入的第3个参数中获取传入requestId的值,类似KEYS[1]取值。

逻辑:
如果通过lockKey获取到的值与传入的requestId相同,则删除lockKey并返回1
否则返回0

总结
一个安全的分布式锁解锁机制,核心思想是:
•使用 Lua 脚本确保原子性操作。
•验证锁的持有者是否匹配,防止误删。
•返回解锁结果,便于调用方判断操作是否成功。
这种设计适用于高并发场景下的分布式锁管理。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值