在集群模式下,redis加锁和解锁如何定位一台机器上?

知其然要知其所以然,探索每一个知识点背后的意义,你知道的越多,你不知道的越多,一起学习,一起进步,如果文章感觉对您有用的话,关注、收藏、点赞,有困惑的地方请评论,我们一起交流!


在 Redis 集群模式下,加锁和解锁操作需要确保针对同一个键(即锁的 Key)的请求被路由到正确的集群节点。Redis 集群通过 哈希槽(Hash Slot) 分配机制实现数据分片,而 Redisson 等客户端库则通过以下策略保证加锁和解锁操作能定位到同一台机器:

一、Redis 集群的数据分片规则

  1. 哈希槽分配

    • Redis 集群将数据划分为 16384 个槽(Slot),每个节点负责一部分槽。
    • 键的所属槽由 CRC16(key) % 16384 计算得出。
    • 例如,锁的 Key 为 my_lock,其槽号为 CRC16("my_lock") % 16384
  2. 客户端路由

    • 客户端通过集群配置知道每个槽所在的节点。
    • 执行命令时,客户端直接向负责该槽的节点发起请求。

二、加锁与解锁的定位机制

1. 加锁时的节点定位

  • 步骤
    1. 客户端计算锁 Key(如 my_lock)的哈希槽。
    2. 根据集群配置找到负责该槽的节点(假设为节点 A)。
    3. 向节点 A 发送加锁命令(如 SET my_lock uuid:threadId NX PX 30000)。
  • 关键点
    • 所有对 my_lock 的请求(包括后续解锁)都会由节点 A 处理。

2. 解锁时的节点定位

  • 步骤
    1. 客户端再次计算 my_lock 的哈希槽,定位到同一节点 A。
    2. 向节点 A 发送解锁的 Lua 脚本(需验证客户端标识)。
  • 原子性保障
    • Lua 脚本在节点 A 上原子化执行,确保解锁操作的安全。

3. 节点故障时的处理

  • 集群自动转移
    • 如果节点 A 宕机,且集群启用了故障转移(如从节点晋升),客户端会:
      1. 收到 MOVEDASK 重定向错误。
      2. 根据错误信息重新向新主节点发起请求。
  • Redisson 的容错
    • Redisson 自动处理重定向,无需用户干预。

三、Redisson 在集群模式下的优化

1. 一致哈希路由

  • Redisson 在客户端缓存 槽与节点的映射关系,避免每次请求都查询集群配置。
  • 当集群拓扑变化时(如节点增减),客户端通过 CLUSTER SLOTS 命令更新缓存。

2. 多锁模式(MultiLock)

  • 场景 :需跨多个键加锁(如 lock1lock2 分布在不同的节点)。

  • 实现

    java 复制代码
    RLock lock1 = redisson.getLock("lock1");
    RLock lock2 = redisson.getLock("lock2");
    RLock multiLock = redisson.getMultiLock(lock1, lock2);
    multiLock.lock();  // 依次向不同节点加锁

3. 看门狗(WatchDog)续期

  • 问题:集群模式下锁的过期时间可能因节点时间不同步导致提前释放。
  • 解决 :Redisson 后台线程定期向原节点发送续期命令(PEXPIRE)。

四、关键注意事项

  1. 避免跨槽事务

    • Redis 集群不支持跨槽事务,确保锁 Key 的哈希槽相同(可通过 {} 强制路由):

      java 复制代码
      // 使用 Hash Tag 确保所有 Key 落到同一槽
      RLock lock = redisson.getLock("{user}:lock");  // 如 "user123:lock"
  2. 网络分区风险

    • 脑裂可能导致多个客户端同时持有锁,需配置 cluster-require-full-coverage no
  3. 性能监控

    • 使用 CLUSTER KEYSLOT 命令检查锁 Key 的槽分布:

      bash 复制代码
      CLUSTER KEYSLOT "my_lock"

五、与其他方案的对比

方案 定位机制 优点 缺点
Redis 集群 哈希槽 + 客户端路由 原生支持,性能高 需处理重定向和故障转移
Redisson 代理 封装集群路由逻辑 对开发者透明 依赖客户端实现
Twemproxy 分片 代理层计算分片 解耦客户端 单点瓶颈,不支持所有命令

六、总结

在 Redis 集群模式下,加锁和解锁的节点定位依赖以下核心机制:

  1. 哈希槽分配 :通过 CRC16(key) % 16384 固定锁 Key 的归属节点。
  2. 客户端路由:Redisson 等库自动处理槽映射和重定向。
  3. 原子性脚本:解锁时通过 Lua 脚本在目标节点上验证和执行。

最佳实践

  • 使用 Hash Tag (如 {resource}:lock)强制锁 Key 分配到同一槽。
  • 启用 WatchDog 防止锁因网络抖动或 GC 暂停超时。
  • 监控集群状态,避免节点负载不均。
相关推荐
刃神太酷啦14 分钟前
类和对象(1)--《Hello C++ Wrold!》(3)--(C/C++)
java·c语言·c++·git·算法·leetcode·github
阿乾之铭18 分钟前
Java后端文件类型检测(防伪造)
java·开发语言
console.log('只想发财')33 分钟前
新手安装java所有工具(jdk、idea,Maven,数据库)
java·maven·intellij-idea
添砖Java中35 分钟前
深入剖析缓存与数据库一致性:Java技术视角下的解决方案与实践
java·数据库·spring boot·spring·缓存·双写一致性
m0_7269659840 分钟前
在IDEA中导入gitee项目
java·gitee·intellij-idea
互联网动态分析41 分钟前
Java:编程世界的常青树与数字化转型的基石
java
浩~~1 小时前
HTML5 中实现盒子水平垂直居中的方法
java·服务器·前端
mtc8n241 小时前
FastExcel 本地开发和Linux上上传Resource文件的差异性
java
天上掉下来个程小白1 小时前
添加购物车-02.代码开发
java·服务器·前端·后端·spring·微信小程序·苍穹外卖