红锁(RedLock):Redis分布式锁的高可用方案

ps:如果这篇帖子对于还在找工作和找实习的你有所帮助,可以关注我,给本贴点赞、评论、收藏并订阅专栏;同时不要吝啬您的花花

红锁(RedLock)是Redis官方提出的分布式锁算法,由Redis作者Salvatore Sanfilippo(antirez)于2014年设计,旨在解决传统单节点Redis锁在分布式环境中的可靠性问题,尤其针对主从复制场景下的锁丢失风险。

一、核心背景与问题

传统单节点Redis锁通过SET key value NX PX ttl命令实现,但存在致命缺陷:

  • 主节点宕机时,若从节点尚未同步锁数据,主从切换会导致锁丢失
  • 单点故障直接导致整个锁服务不可用

红锁通过多节点冗余+多数派共识机制,彻底解决这些问题。

二、核心设计思想

红锁借鉴分布式一致性算法(Paxos/Raft)的多数派原则,核心思路:

部署N个完全独立的Redis主节点(通常为5个,奇数个),客户端必须在超过半数(N/2+1)节点上成功加锁,才算真正获得锁。

这样即使部分节点故障(≤N/2-1),锁服务仍能正常运行,且不会出现锁丢失问题。

三、完整工作流程

1. 加锁流程 🔒

1

记录开始时间

获取当前时间戳T1,用于计算总耗时

2

依次申请锁

向所有N个独立Redis节点发送SET key UUID NX PX ttl命令

UUID:唯一客户端标识,防止误解锁

NX:仅当key不存在时设置

PX:设置过期时间(毫秒)

3

验证结果

统计成功加锁节点数

成功节点数 ≥ N/2+1

总耗时(T2-T1) < 锁过期时间

同时满足则加锁成功

4

计算剩余时间

锁有效时间 = 预设ttl - 总耗时,用于后续续期

5

失败处理

若加锁失败,立即向所有节点发送解锁命令,避免死锁

2. 解锁流程 🗝️

  1. 向所有Redis节点发送解锁命令:EVAL "if redis.call('get',KEYS[1]) == ARGV[1] then return redis.call('del',KEYS[1]) else return 0 end" 1 key UUID
  2. 无论节点是否加锁成功,都必须发送解锁命令,确保清理所有可能的残留锁

3. 锁续期 ⏳

  • 加锁成功后,客户端需在锁过期前完成业务操作
  • 若操作超时,可通过向成功加锁的节点发送续期命令延长锁有效期
  • 续期失败时应立即放弃操作并解锁

四、部署与配置要求

  1. 节点数量:推荐5个独立Redis主节点(奇数),确保多数派(3个)能形成有效共识
  2. 节点独立性:无主从复制关系,完全独立运行物理上分布在不同服务器/机房,避免单点故障
  3. 客户端实现:必须使用相同的key和UUID向所有节点申请锁加锁超时时间应远小于锁的TTL,防止网络延迟导致误判

五、红锁 vs 单节点Redis锁

可靠性

低(主从切换易丢锁)

高(多数派保障,容忍≤N/2-1节点故障)

部署复杂度

简单(1个节点)

复杂(至少3-5个独立节点)

性能

高(单次网络请求)

中(多次网络请求,需遍历所有节点)

一致性

弱(依赖主从同步)

强(多数派共识)

适用场景

低并发、非核心业务

高并发、核心业务(如支付、库存扣减)

六、优缺点分析

优点 ✅

  1. 高可用性:容忍部分节点故障,锁服务持续可用
  2. 安全性:多数派原则确保不会出现锁丢失或重复获取问题
  3. 分布式一致性:借鉴Paxos/Raft思想,提供更强的一致性保障

缺点 ⚠️

  1. 部署成本高:需要多个独立Redis节点,运维复杂度增加
  2. 性能开销大:多次网络往返,延迟高于单节点锁
  3. 时钟同步要求:节点间时钟偏差过大会导致锁有效性判断错误,需配置NTP服务同步时间
  4. 存在争议:分布式系统专家对红锁的安全性存在学术争议,需结合业务场景评估

七、适用场景

  1. 核心业务:支付、订单、库存等对数据一致性要求极高的场景
  2. 高可用需求:需要避免单点故障导致业务中断的系统
  3. 跨区域部署:分布式系统中节点分布在不同机房/地区的场景

八、Java实现示例(Redisson)

// 1. 创建5个独立Redis客户端
Config config1 = new Config();
config1.useSingleServer().setAddress("redis://192.168.1.1:6379");
RedissonClient client1 = Redisson.create(config1);

// 同理创建client2, client3, client4, client5...

// 2. 获取各节点锁对象
RLock lock1 = client1.getLock("myLock");
RLock lock2 = client2.getLock("myLock");
RLock lock3 = client3.getLock("myLock");
RLock lock4 = client4.getLock("myLock");
RLock lock5 = client5.getLock("myLock");

// 3. 创建红锁
RedissonRedLock redLock = new RedissonRedLock(lock1, lock2, lock3, lock4, lock5);

// 4. 加锁(最多等待100秒,自动释放30秒)
boolean isLocked = redLock.tryLock(100, 30, TimeUnit.SECONDS);
if (isLocked) {
    try {
        // 执行业务逻辑
        processOrder();
    } finally {
        // 5. 解锁
        redLock.unlock();
    }
}

九、关键注意事项

  1. 时间同步:所有Redis节点和客户端必须通过NTP服务同步时间,误差控制在50ms以内
  2. 锁超时设置:TTL应根据业务实际耗时设置,避免过短导致锁提前释放,过长导致死锁风险
  3. 失败处理:加锁失败时必须立即解锁所有节点,防止残留锁影响其他客户端
  4. 网络分区:需处理网络分区导致的节点通信失败,避免误判锁状态
  5. 性能优化:可通过异步请求多个节点提高加锁效率,减少延迟

ps:如果这篇帖子对于还在找工作和找实习的你有所帮助,可以关注我,给本贴点赞、评论、收藏并订阅专栏;同时不要吝啬您的花花

Redis分布式锁 文章被收录于专栏

本专栏聚焦 Redis 分布式锁从原理到生产落地全流程,拆解SET 原子加锁、Lua 解锁、锁续期、Redlock等核心技术,直击锁超时、误释放、主从一致性等高频痛点。结合 Redisson 实战与微服务场景案例,输出可直接复用的代码方案与避坑指南,助力后端工程师攻克分布式并发难题,构建高可靠锁服务。

全部评论

相关推荐

zzzilik:但凡有一段 ai 相关经历实习,基本都进了,除了阿里云感觉卡硕
校招笔试
点赞 评论 收藏
分享
03-21 23:46
已编辑
腾讯_后台开发(实习员工)
实则已经躺了几个月了想起来牛客还有个号..bg:&nbsp;211本,1段BAT半年实习+2段中厂实习(实则还有数不清的小厂实习,没待多久就不写了),网安转测试转后端版秋招总结:(2ssp➕3sp➕1🥬&nbsp;&nbsp;)小红书&nbsp;offer拼多多&nbsp;offer腾讯音乐&nbsp;offer滴滴&nbsp;offer作业帮&nbsp;offer招银&nbsp;offer&nbsp;烂🥬其他公司简历挂了很多,一面挂了很多,看过我帖子的朋友也知道我曾达成秋招连续&nbsp;11&nbsp;次一面挂,黑暗的&nbsp;9&nbsp;月经验:1.&nbsp;秋招要早投我是很早就投了,秋招开了没一周就全投了,总共42次面试。你得有面试的机会才有机会拿&nbsp;offer有朋友跟我类似bg,晚投了半个月,只有6次面试。。2.&nbsp;利用面试多补齐简历漏洞比如面试官更想知道你做的需求的价值,需求的上下游是怎么样的,遇到&nbsp;bug&nbsp;怎么定位的?每次面试后多总结总结3.&nbsp;运气太重要了有时没有面试或者拿不到&nbsp;offer&nbsp;只是差了点运气,不要觉得自己的能力有问题4.&nbsp;不要&nbsp;all&nbsp;in&nbsp;实习转正本人转正失败,但转正前我就开始准备秋招了身边有朋友&nbsp;all&nbsp;in&nbsp;转正直到&nbsp;11&nbsp;月,后面还被鸽了,还错过了秋招投递最佳时间感概:从开始实习到现在,转眼已经一年半了,我终于摆脱了实习生的身份。终于混成正职了!记录一下㊗️大家秋招春招实习工作都顺利!
腾讯音乐求职进展汇总
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务