在集群模式下,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. 收到 MOVED 或 ASK 重定向错误。
      2. 根据错误信息重新向新主节点发起请求。
  • Redisson 的容错 :
    • Redisson 自动处理重定向,无需用户干预。

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

1. 一致哈希路由

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

2. 多锁模式(MultiLock)

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

  • 实现 :

    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 暂停超时。
  • 监控集群状态,避免节点负载不均。
相关推荐
hai_android6 分钟前
Android 设备锁定:Kiosk Mode 实战
android·java·android jetpack
张伯毅14 分钟前
External Shuffle Service(spark3_shuffle):原理、配置与排障
java·开发语言·spark·yarn
弦儿15 分钟前
从零认识 Maven:依赖管理 + 项目构建 + 单元测试知识点全梳理(附 IDEA 实操)
后端
Bazingga19 分钟前
多智能体编排:拆分、隔离与收敛的完整实战
后端·agent·ai编程
geovindu33 分钟前
rust: Template Method Pattern
开发语言·后端·设计模式·rust·行为模式·模板方法模
high一马平川38 分钟前
# SystemUI Dagger2 精读 · 第 2 章 @Inject:1200 处构造注入,和 1 处例外
android·java·kotlin
小陈从不会敲代码39 分钟前
JavaEE面试复习(多线程-初阶)
java·面试·java-ee
BingoGo39 分钟前
PHP 8.7 协程新提案 让跨协程代码共享请求身份
后端·php
周厉40 分钟前
酒店PMS系统设计:房型房价管理与动态价格优先级实现(Java/MySQL)
java·数据库·pms酒店系统
一碗白开水一1 小时前
Day 5 · 弹性 | 微观
java·前端·数据库