在集群模式下,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 暂停超时。
  • 监控集群状态,避免节点负载不均。
相关推荐
float_六七3 小时前
IntelliJ IDEA双击Ctrl的妙用
java·ide·intellij-idea
能摆一天是一天5 小时前
JAVA stream().flatMap()
java·windows
颜如玉5 小时前
🤲🏻🤲🏻🤲🏻临时重定向一定要能重定向🤲🏻🤲🏻🤲🏻
java·http·源码
程序员爱钓鱼6 小时前
Go语言实战案例 — 工具开发篇:实现一个图片批量压缩工具
后端·google·go
程序员的世界你不懂7 小时前
【Flask】测试平台开发,新增说明书编写和展示功能 第二十三篇
java·前端·数据库
星空寻流年7 小时前
设计模式第一章(建造者模式)
java·设计模式·建造者模式
在未来等你7 小时前
Kafka面试精讲 Day 13:故障检测与自动恢复
大数据·分布式·面试·kafka·消息队列
gb42152878 小时前
java中将租户ID包装为JSQLParser的StringValue表达式对象,JSQLParser指的是?
java·开发语言·python
曾经的三心草8 小时前
Python2-工具安装使用-anaconda-jupyter-PyCharm-Matplotlib
android·java·服务器
Metaphor6928 小时前
Java 高效处理 Word 文档:查找并替换文本的全面指南
java·经验分享·word