Redisson的watchdog机制是怎么样的?

1 个回答

  • 劳拉
    你会等一个人三五年吗?
    Redisson 的 `watchdog` 机制是一种自动续租的功能,用于防止 Redis 分布式锁在任务未完成时因超时而失效。以下是详细说明: ### 1. 自动续租 当 Redisson 客户端实例获得一个分布式锁时,如果未指定锁的超时时间,`watchdog` 会自动启动一个后台任务来定期续租锁的过期时间。续期频率为锁租约时间的 1/3。例如,默认的锁租约为 30 秒,则 `watchdog` 每隔 10 秒会将锁的 TTL 续期 30 秒,确保在处理长时间任务时锁不会过期。 ### 2. 续期时长和间隔 默认情况下,`watchdog` 每 10 秒进行一次续期,将锁的过期时间重置为 30 秒。这通过 `scheduleExpirationRenewal` 方法实现,该方法利用 Netty 的时间轮(TimerTask)来定时续期。 ### 3. 停止续期 当锁被显式释放或 Redisson 客户端实例被关闭时,`watchdog` 会停止相应的续租任务,以避免不必要的续期。具体来说: - **EXPIRATION_RENEWAL_MAP**:Redisson 使用一个名为 `EXPIRATION_RENEWAL_MAP` 的映射来管理锁的续租任务,`unlock` 方法会将相应的任务从该映射中移除。 - **异常情况**:在 `unlockAsync` 方法中,无论解锁是否成功,Redisson 都会调用 `cancelExpirationRenewal` 来停止续期。 ### 4. 续期实现原理 `watchdog` 主要通过 `scheduleExpirationRenewal` 方法实现续期任务,代码简化如下: ```java protected 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); try { renewExpiration(); // 续期锁的过期时间 } finally { if (Thread.currentThread().isInterrupted()) { cancelExpirationRenewal(threadId); } } } } ``` 在该方法中: - `renewExpiration` 会向 Redis 发送续期命令,以延长锁的 TTL。 - 如果线程被中断,则会调用 `cancelExpirationRenewal` 停止续期,避免无效的续期任务。 ### 5. 续期条件 仅在未指定锁的超时时间(`leaseTime <= 0`)时才会启动 `watchdog` 续期。如果指定了锁的过期时间,Redisson 不会进行自动续期,锁会在到达设定的过期时间后自动释放。 ### 6. 停止续期的条件 - 当锁的 `unlock` 方法被调用,或者客户端实例关闭时,会停止续期。 - 当线程中断时,也会取消续期,避免资源占用。 停止续期的核心代码如下: ```java protected void cancelExpirationRenewal(Long threadId) { ExpirationEntry task = EXPIRATION_RENEWAL_MAP.get(getEntryName()); if (task == null) { return; } if (threadId != null) { task.removeThreadId(threadId); } if (threadId == null || task.hasNoThreads()) { Timeout timeout = task.getTimeout(); if (timeout != null) { timeout.cancel(); } EXPIRATION_RENEWAL_MAP.remove(getEntryName()); } } ``` ### 7. 宕机处理 Redisson 的续期机制依赖于 Netty 的时间轮(TimerTask、Timeout 和 Timer)并基于 JVM 运行环境。若应用宕机、下线或重启,续租任务将终止,从而避免因服务崩溃导致锁长时间不释放的死锁问题。 ### 总结 `watchdog` 自动续租机制在锁超时时间未指定时有效,默认每 10 秒续期一次,延长锁的有效期到 30 秒,直到锁被释放、应用中断或线程被中断才会终止。Redisson 的 `watchdog` 机制通过这种简单而有效的方式保证了 Redis 锁在分布式环境下的有效性和可靠性。
    发布于 2024-10-26 14:50 •IP属地 浙江
    举报
    评论
    收藏