在集群模式下,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 暂停超时。
  • 监控集群状态,避免节点负载不均。
相关推荐
短剑重铸之日39 分钟前
《ShardingSphere解读》07 读写分离:如何集成分库分表+数据库主从架构?
java·数据库·后端·架构·shardingsphere·分库分表
知我Deja_Vu40 分钟前
【避坑指南】ConcurrentHashMap 并发计数优化实战
java·开发语言·python
wefly20172 小时前
m3u8live.cn 在线M3U8播放器,免安装高效验流排错
前端·后端·python·音视频·前端开发工具
daidaidaiyu2 小时前
Spring IOC 源码学习 事务相关的 BeanDefinition 解析过程 (XML)
java·spring
zhanggongzichu2 小时前
小白怎么理解后端分层概念
后端·全栈
鬼蛟3 小时前
Spring————事务
android·java·spring
西门吹-禅3 小时前
【sap fiori cds up error】
java·服务器·sap cap cds
stark张宇3 小时前
Golang后端面试复盘:从Swoole到IM架构,如何支撑360w用户的实时消息推送?
后端
小码哥_常4 小时前
从0到1:搭建Spring Boot 3企业级认证授权平台
后端
敲代码的嘎仔4 小时前
Java后端面试——SSM框架面试题
java·面试·职场和发展·mybatis·ssm·springboot·八股