Redisson分布式锁实现原理

1. 加锁机制

核心流程

  1. 尝试加锁
    • 客户端通过执行 Lua脚本 向Redis发送加锁请求,保证原子性操作。
  2. 锁存储结构
    • Redis中存储的锁是一个 Hash结构
      • Key:锁名称(唯一标识)
      • Field:客户端ID(UUID + 线程ID)
      • Value:重入次数(支持可重入锁)
  3. 锁超时时间
    • 默认30秒,超时自动释放(避免死锁)。

Lua脚本

-- KEYS = 锁名称, ARGV = 超时时间(毫秒), 客户端ID
if (redis.call('exists', KEYS) == 0) then
    redis.call('hset', KEYS, ARGV, 1);
    redis.call('pexpire', KEYS, ARGV);
    return nil;
end;
if (redis.call('hexists', KEYS, ARGV) == 1) then
    redis.call('hincrby', KEYS, ARGV, 1);
    redis.call('pexpire', KEYS, ARGV);
    return nil;
end;
return redis.call('pttl', KEYS);

2. 锁自动续期(Watchdog)

看门狗机制

  • 问题:业务执行时间超过锁超时时间,导致锁提前释放。
  • 解决方案
    1. 客户端加锁成功后,启动后台线程(Watchdog)。
    2. 每隔 超时时间的1/3(默认10秒) 自动续期锁。
    3. 业务完成后,Watchdog自动停止。

续期Lua脚本

-- KEYS = 锁名称, ARGV = 超时时间(毫秒), 客户端ID
if (redis.call('hexists', KEYS, ARGV) == 1) then
    redis.call('pexpire', KEYS, ARGV);
    return 1;
end;
return 0;

3. 释放锁流程

释放逻辑

  1. 检查当前线程是否是锁的持有者。
  2. 如果是,重入次数减1;若重入次数为0,删除锁。
  3. 取消Watchdog续期任务。

Lua脚本

-- KEYS = 锁名称, Channel, ARGV = 客户端ID, 释放消息
if (redis.call('hexists', KEYS, ARGV) == 0) then
    return nil;
end;
local counter = redis.call('hincrby', KEYS, ARGV, -1);
if (counter > 0) then
    redis.call('pexpire', KEYS, ARGV);
    return 0;
else
    redis.call('del', KEYS);
    redis.call('publish', KEYS, ARGV);
    return 1;
end;
return nil;

4. 高可用性设计

Redis部署模式

模式特点
单节点简单,适用于低并发场景
主从模式主节点宕机时可能丢失锁(异步复制)
哨兵模式自动切换主节点,提高可用性
集群模式通过哈希槽分配锁,支持高并发和高可用

红锁(RedLock)

  1. 客户端向多个Redis节点(≥3)请求加锁。
  2. 多数节点(N/2+1)加锁成功时,视为成功。
  3. 锁有效时间 = 锁超时时间 - 获取锁总耗时。

5. 核心优势

  • 可重入锁:同一线程可多次获取同一锁。
  • 自动续期:通过Watchdog避免锁超时释放。
  • 高可用:支持多种Redis部署模式。
  • 锁类型丰富:公平锁、非公平锁(RLock)。

6. 注意事项

  1. 网络延迟:可能导致锁超时失效。
  2. 时钟漂移:需使用NTP同步时钟。
  3. 业务超时:依赖Watchdog,需避免业务无限阻塞。

7. 业务逻辑无限阻塞处理方案

代码层面预防

措施实现方式
业务逻辑超时控制使用Future、线程中断机制
合理设置锁超时时间不依赖WatchDog,直接指定超时时间

应急处理

措施工具/技术
监控告警 + 手动释放Redis CLI、Prometheus监控
重启服务Kubernetes健康检查(livenessProbe
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值