Plantre Plantre
首页
后端
技术
硬件
  • 前端文章

    • HTML
    • CSS
    • JavaScript
  • 技术

    • 技术文档
    • GitHub技巧
    • Nodejs
    • 博客搭建
  • 学习笔记

    • 《JavaScript教程》
    • 《JavaScript高级程序设计》
    • 《ES6 教程》
    • 《Vue》
    • 《React》
    • 《TypeScript 从零实现 axios》
    • 《Git》
    • TypeScript
    • JS设计模式总结
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

plantre

一个后端开发者
首页
后端
技术
硬件
  • 前端文章

    • HTML
    • CSS
    • JavaScript
  • 技术

    • 技术文档
    • GitHub技巧
    • Nodejs
    • 博客搭建
  • 学习笔记

    • 《JavaScript教程》
    • 《JavaScript高级程序设计》
    • 《ES6 教程》
    • 《Vue》
    • 《React》
    • 《TypeScript 从零实现 axios》
    • 《Git》
    • TypeScript
    • JS设计模式总结
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 计算机组成原理

  • 操作系统

  • 计算机网络

  • 设计模式

  • Java

  • Spring

  • SpringCloud

  • MySQL

  • Redis

  • 分布式

    • 理论等

    • 分布式算法

    • 分布式事务

    • 分布式锁

      • ​​Redis3主3从时怎么用分布式锁
      • SpringCloud

    • Zookeeper

    • Dubbo

    • Kafka

    • 数据结构

    • 算法

    • OJ

    • 从道家哲学看计算机?
    • 后端
    • 分布式
    • 分布式锁
    plantre
    2025-06-19
    目录

    ​​Redis3主3从时怎么用分布式锁

    在 Redis 3主3从集群中实现分布式锁时,需结合 Redis Cluster 的特性和分布式锁的核心原则(互斥性、容错性、避免死锁)设计。以下是具体方案及注意事项:


    # 🔒 一、基础方案:单节点锁(适用于低要求场景)

    # 实现步骤

    1. 加锁命令
      使用 SET key unique_value NX PX 30000 命令:

      • NX:仅当 Key 不存在时设置,保证互斥性。
      • PX 30000:设置 30 秒超时,避免死锁。
      • unique_value:使用 UUID 或线程 ID 标识锁持有者。
    2. 释放锁
      通过 Lua 脚本原子化释放(避免误删其他客户端的锁):

      if redis.call("GET", KEYS[1]) == ARGV[1] then 
          return redis.call("DEL", KEYS[1]) 
      else 
          return 0 
      end
      
      1
      2
      3
      4
      5

    # 风险

    • 主从切换导致锁丢失
      主节点加锁后数据未同步到从节点时,若主节点宕机,从节点升级后无锁数据,导致其他客户端可重复加锁。
    • 锁续期问题
      业务执行超时需手动续期(Watch Dog 机制),否则锁自动失效。

    适用场景:对锁可靠性要求不高的业务(如缓存更新)。


    # ⚙️ 二、高可用方案:RedLock 算法(官方推荐)

    针对主从容错问题,Redis 作者提出 RedLock 算法,通过多节点投票机制提升可靠性。

    # 实现流程

    1. 部署独立节点
      3主3从集群中,将 3个主节点视为独立节点(从节点仅用于备份,不参与锁决策)。

    2. 加锁步骤:

      1. 生成全局唯一 ID(如 UUID)作为锁标识。
      2. 向所有主节点顺序发送加锁命令(SET key uuid NX PX TTL),并记录操作开始时间 T1。
      3. 计算总耗时 T_total = T2 - T1(T2 为收到最后一个响应的时间),需满足:
        • T_total < 锁超时时间(防止锁自动失效)。
        • 成功节点数 ≥ N/2 + 1(3节点时需至少2个成功)。
      4. 若成功,锁实际有效时间 = TTL - T_total - 时钟漂移补偿。
    3. 释放锁:
      向所有主节点发送 Lua 脚本释放锁(即使未成功加锁的节点也需尝试)。

    # 参数配置

    参数 建议值 说明
    锁超时时间(TTL) 10s-30s 需大于业务最大耗时
    重试间隔 100-300ms 避免频繁重试压垮节点
    续期间隔 TTL/3(如10s) Watch Dog 续期频率

    # 生产级工具

    推荐使用 Redisson 库(支持自动续期、可重入锁、RedLock 封装):

    RedissonClient client = Redisson.create();
    RLock lock1 = client.getLock("lock1");
    RLock lock2 = client.getLock("lock2");
    RLock lock3 = client.getLock("lock3");
    RedissonRedLock redLock = new RedissonRedLock(lock1, lock2, lock3);
    
    try {
        if (redLock.tryLock(5, 30, TimeUnit.SECONDS)) { // 尝试5秒,锁有效期30秒
            // 执行业务逻辑
        }
    } finally {
        redLock.unlock();
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13

    # ⚠️ 三、关键注意事项

    1. 时钟同步问题
      节点间时钟漂移可能导致锁提前失效。建议通过 NTP 协议同步时间。

    2. GC 停顿风险
      客户端长时间 GC 可能导致锁过期后误操作资源。需设置合理的 TTL 并监控 GC 时间。

    3. 节点故障恢复
      节点崩溃后若未持久化锁数据,恢复后可能与其他节点状态冲突。建议开启 AOF 持久化。

    4. 性能与可靠性权衡

      • 单节点锁:性能高,但可靠性低(仅用于非关键任务)。
      • RedLock:可靠性高,但多节点通信增加延迟(适合金融等高要求场景)。
    5. 锁粒度控制
      锁 Key 需精确到业务资源(如 order_123),避免全局锁竞争。


    # 💎 四、生产环境推荐方案

    场景 方案 工具
    非关键任务(如缓存更新) 单节点锁 + Lua 释放 Spring Data Redis
    高并发业务(如订单支付) RedLock 多节点投票 Redisson 库
    强一致性要求(如库存扣减) 结合数据库事务 + Redis 锁兜底 Seata + Redisson

    注:Redis Cluster 的 3主3从架构中,RedLock 只需操作 3 个主节点(N=3),满足 N/2 + 1 = 2 的成功条件即可。


    # 📚 五、扩展阅读:RedLock 的争议与替代

    • 争议点:极端场景下(如网络分区 + GC 停顿)仍可能锁失效。
    • 替代方案:
      • ZooKeeper 锁:基于 ZAB 协议强一致,但性能低于 Redis。
      • etcd 锁:基于 Raft 协议,适合对一致性要求极高的场景。

    建议根据业务容忍度选择方案:Redis 锁适用于 AP 系统(高可用优先),ZK/etcd 适用于 CP 系统(强一致优先)。

    编辑 (opens new window)
    上次更新: 2025/06/24, 00:41:57
    Seata支持几种分布式事务
    docker搭建Zookeeper集群

    ← Seata支持几种分布式事务 docker搭建Zookeeper集群→

    最近更新
    01
    集成loki
    07-04
    02
    TCP的ESTABLISHED是什么意思
    06-24
    03
    安装1panel
    06-24
    更多文章>
    Theme by Vdoing | Copyright © 2025-2025 plantre | MIT License
    • 跟随系统
    • 浅色模式
    • 深色模式
    • 阅读模式