当前位置: 首页 > news >正文

Redisson 看门狗机制深度解析:分布式锁的守护者

Redisson 看门狗机制深度解析:分布式锁的守护者

本文深入剖析 Redisson 的看门狗(Watchdog)机制在分布式锁中的关键作用,涵盖工作机制、源码实现及生产实践要点。


一、问题背景:分布式锁的致命缺陷

传统Redis锁实现痛点
// 基础Redis分布式锁实现
Boolean locked = redis.setnx("lock_key", "value");
if (locked) {
redis.expire("lock_key", 30); // 设置过期时间
try {
// 业务逻辑
} finally {
redis.del("lock_key"); // 释放锁
}
}

核心缺陷

  1. 业务执行时间 > 锁超时时间 → 锁提前失效
  2. 客户端崩溃 → 锁无法释放
  3. 时钟漂移 → 锁时间计算错误

二、Redisson 看门狗机制设计

核心功能架构
加锁请求
创建锁记录
是否指定超时
启动看门狗线程
普通锁
周期性续期
业务完成
取消续期
核心组件
  1. 锁续期器(ExpirationEntry)
  2. 看门狗线程池
  3. 异步回调链
  4. 锁释放监听器

三、工作机制全流程

ClientRedissonRedislockClient->>Redisson: lock() // 获取锁SET lock_key UUID:threadId NX EX 30s成功启动看门狗线程PEXPIRE lock_key 30000续期成功loop[每10秒执行]unlock() // 释放锁DEL lock_key终止看门狗线程ClientRedissonRedis
关键步骤解析:
  1. **锁获取阶段解析:
  2. 锁获取阶段
  • 默认设置30秒过期时间(可通过Config.lockWatchdogTimeout修改)
  • 值格式:UUID:threadId(如4b2f5c3e-af78-491a-b3f6-8a813c7d4f3b:1
  1. 看门狗激活条件
// 显式指定leaseTime会禁用看式指定leaseTime会禁用看门狗
lock.lock(10, TimeUnit.SECONDS); // 无看门狗
lock.lock(); // 激活看门狗
  1. 续期策略
  • 首次续期间隔 = 锁超时时间 / 3 = 10秒
  • 每次续期将过期时间重置为完整30秒
  • 通过pexpire命令保证原子性操作
  1. 锁释放阶段
  • 通过Lua脚本原子性释放锁(校验UUID+threadId)
  • 释放后立即取消看门狗任务

四、源码级实现剖析(Redisson 3.17.7)

1. 锁入口逻辑
// RedissonLock.java
public void lock() {
try {
lock(-1, null, false);// leaseTime=-1 触发看门狗
} catch (InterruptedException e) {
throw new IllegalStateException();
}
}
2. 看门狗调度核心
// RedissonLock.java
private void scheduleExpirationRenewal(long threadId) {
ExpirationEntry entry = new ExpirationEntry();
ExpirationEntry oldEntry = EXPIRATION_RENEWAL_MAP.putIfAbsent(getEntryName(), entry);if (oldEntry != null) {
oldEntry.addThreadId(threadId);
} else {
entry.addThreadId(threadId);
renewExpiration();// 启动续期任务
}
}
3. 续期任务实现
// RedissonLock.java
private void renewExpiration() {
Timeout task = commandExecutor.getConnectionManager()
.newTimeout(new TimerTask()
.newTimeout(new TimerTask() {
public void run(Timeout timeout) {
ExpirationEntry ent = EXPIRATION_RENEWAL_MAP.get(getEntryName());
if (ent == null) return;
if (ent == null) return;Long threadId = ent.getFirstThreadId();
if (threadId == null) return;// 异步续期调用
RFuture<Boolean> future = renewExpirationAsync(threadId);
future.onComplete((res, e) -> {
if (e != null) {
log.error("Can't update lock expiration", e);
return;
}if (res) {
// 递归调用实现周期性续期
renewExp周期性续期
renewExpiration();
}
});
}
}, internalLockLeaseTime / 3, TimeUnit.MILLIS 3, TimeUnit.MILLISECONDS); // 10秒延迟ee.setTimeout(task);
}
4. 异步续期命令
// RedissonLock.java
protected RFuture<Boolean> renewExpirationAsync(long threadId) {
return evalWriteAsync(getRawName(),
LongCodec.INSTANCE, RedisCommands.EVAL_BOOLEAN,
"if (redis.call('hexists', KEYS[1], ARGV[2]) == 1) then " +
"redis.call('pexpire', KEYS[1], ARGV[1]); " +
"return 1; " +
"end; " +
"return 0;",
Collections.sreturn 0;",
Collections.singletonList(getRawName()),
internalLockLeaseTime, getLockName(threadId));
}

五、生产环境实践要点

1. 关键配置参数
参数默认值建议值作用
lockWatchdogTimeout300lockWatchdogTimeout`30000 ms60000 ms
retryInterval1500 ms300 ms锁获取重试间隔
retryAttempts35锁获取最大尝试次数

配置示例:

Config config = new Config();
config.setLockWatchdogTimeout(60_000);
RedissonClient redisson = Redisson.create(config);
2. 异常场景处理策略
故障类型看门狗行为解决方案
客户端崩溃锁自动超时释放无需干预
网络分区续期失败释放锁增加超时时间
Redis主从切换锁状态不一致启用RedLock
长时间GC可能续期失败优化JVM参数
3. 性能优化建议
  1. 避免长事务:单次持锁时间 < 看门狗超时时间
  2. 合理设置超时:根据P99业务耗时动态调整
  3. 级联锁优化:使用MultiLock管理关联资源
  4. 监控续期频率
# Redisson监控指标
redisson_execution_latency{name="lock_expiration"}
redisson_connections_active

六、与其它方案的对比

特性Redisson看门狗基于ZooKeeperetcd租约续期
续期自动化
网络开销低(仅续期命令)高(维持会话)
时钟依赖强依赖强依赖
客户端复杂度
跨语言支持完善完善完善

七、最佳实践场景

1. 电商订单处理
RLock lock = redisson.getLock("order:"+orderId);
try {
lock.lock(); // 自动续期保护支付流程
processPayment(orderId);
updateInventory(orderId);
} finally {
lock.unlock();
}
2. 分布式任务调度
  1. 分布式任务调度
public void executeTask() {
if (lock.tryLock()) {
try {
// 长时间任务安全执行
runHourlyReport();
} finally {
lock.unlock();
}
}
}
3. 敏感操作防护
// 金融账户变更
if (lock.tryLock(0, 30, SECONDS)) {
try {
updateAccountBalance(userId, amount);
} finally {
lock.unlock();
}
}

总结

Redisson的看门狗机制通过三重保障解决分布式锁核心痛点:

  1. 自动续期:守护线程定期延长锁生命周期
  2. 崩溃安全:超时机制防止死锁
  3. 原子操作:Lua脚本保证操作原子性

使用建议

  • 关键业务使用默认看门狗模式(不指定leaseTime)
  • 短任务可手动设置超时提升性能
  • 配合Redisson的RedLock实现多实例容错
  • 监控续期成功率指标redisson_lock_expiration_success
http://www.dtcms.com/a/461068.html

相关文章:

  • 非预置应用使用platform签名并且添加了android.uid.system无法adb安装解决方法
  • 分布式光纤声波振动传感:守护智慧城市燃气管网安全的 “神经末梢”
  • Hadoop 3.3.5 伪分布式安装配置的完整过程
  • 郑州市中原区建设局网站南京市建设工程档案馆网站
  • Oracle PL/SQL Developer v16的安装以及导出导入表数据
  • 消防管理系统如何重构现代空间防御体系
  • Coze源码分析-资源库-编辑数据库-后端源码-流程/技术/总结
  • Linux之lvm存储卷管理篇
  • 数字大健康浪潮下:智能设备重构人力生态,传统技艺如何新生?
  • 郑州陆港开发建设有限公司网站西安有哪些家做网站的公司
  • 整体设计 逻辑系统程序 之19 内核层最大资本箱为核心的完整设计讨论— 含分层架构、CNN 数据处理支撑、监督闭环与多场景交付物
  • GPT系列模型-详解
  • 【pytest 】 pytest 生命周期
  • DMAIC各个阶段用到的图
  • 企业网站建设 网络服务dedecms网站后台模板修改
  • 国外网站开发现状毕业设计做网站教程
  • 【鸿蒙心迹】参加ICT大赛对我的影响和帮助
  • 从轮询到实时推送:将站内消息接口改造为 WebSocket 服务
  • 海口小微企业网站建设公司注册写10万还是50万好
  • 第四部分:VTK常用类详解(第124章 vtkFlyingEdges3D飞行边缘3D类)
  • 混合云新篇章:H100裸金属租赁与云计算的协同效应
  • 第二章:动态 Prompt 管理与多科室智能问答系统
  • 【项目实战 Day12】springboot + vue 苍穹外卖系统(Apache POI + 工作台模块 + Excel表格导出 完结)
  • 微信小程序-8-电影数据布局案例和对话框及本地存储的应用
  • SD:Ubuntu 系统 stable diffusion Web UI - 安装更多插件
  • 什么是负载均衡?
  • 前端框架学习指南:提升开发效率
  • Avast Cleanup安卓版(手机清理优化) 修改版
  • c++多线程(6)------ 条件变量
  • 旅游网站建设与网页设计大连做网站报价