【Redis】告别锁失效:RedLock 与 ZooKeeper 分布式锁原理与实战对比

红锁(RedLock)

先回顾问题:普通 Redis 锁为啥会失效?

你想租一个单间(分布式锁),房东只有 1 把钥匙(单 Redis 主节点),你拿到钥匙锁了门(加锁成功),但房东还没来得及把「你锁门」的消息告诉隔壁中介(从节点),房东就突然失联了(主节点宕机)。隔壁中介接手后(从节点升级为主),不知道你锁了门,又把钥匙给了另一个租客(其他客户端加锁),结果你们俩都能进这个房间 ------ 这就是普通 Redis 锁的主从一致性问题。

红锁的核心逻辑:「多把钥匙,过半才算数」

红锁的思路很简单:不依赖单把钥匙,而是找 3 个及以上独立的房东(独立 Redis 节点,无主从关系),必须拿到「超过一半房东」的钥匙,才算真正锁上门。

具体步骤(用 3 个房东举例,核心是「过半」):
  1. 你找房东 A、B、C 分别要钥匙(向 3 个独立 Redis 节点发起加锁请求);
  2. 拿到至少 2 把钥匙(过半)才算成功:
    • 如果你拿到 A 和 B 的钥匙,哪怕 C 拒绝 / 失联,也算「锁门成功」;
    • 如果你只拿到 A 的钥匙(不足半),就不算锁成功,得把拿到的钥匙都还回去(解锁所有节点);
  1. 其他租客想锁门,必须也拿到至少 2 把钥匙:
    • 因为你已经拿了 A 和 B 的钥匙,其他租客最多只能拿到 C 的,不足半,所以根本锁不了门;
  1. 就算 1 个房东失联(节点宕机)也不怕:
    • 比如房东 A 失联了,你手里还有 B 的钥匙,其他租客最多拿到 C 的,还是不足半,锁依然有效;
  1. 你走的时候,把所有房东的钥匙都还回去(解锁所有节点),其他租客才能重新抢钥匙。

核心关键点(通俗总结):

  1. 节点必须独立:3 个房东互不认识、不互通消息(无主从同步),避免「一个失联,全乱套」;
  2. 过半是核心:3 个节点要拿≥2 把,5 个节点要拿≥3 把,只要超过一半,锁就安全;
  3. 超时要控制:找每个房东要钥匙的总时间,不能超过你计划锁门的时间的一半(比如你想锁 30 秒,找 3 个房东的总耗时不能超过 15 秒),避免钥匙还没拿完,之前拿到的已经过期了。

红锁为啥能解决主从问题?

普通锁是「一根绳上的蚂蚱」,主节点宕机就全完;红锁是「多根绳」,只要超过一半的绳没断(节点正常),锁就不会失效。哪怕 1 个节点宕机,剩下的节点还能保证「只有一个人能拿到过半钥匙」,不会出现多人同时锁门的情况。

红锁的缺点(还是用租房举例):

  1. 麻烦又慢:找 3 个房东要钥匙,比找 1 个费时间(性能下降);
  2. 成本高:要养 3 个独立的房东(部署 3 组 Redis 节点),花钱又费精力(运维成本高);
  3. 极端情况仍有风险:如果 3 个房东的手表时间不一致(节点时钟偏移),可能出现「你以为还拿着钥匙,其实已经过期」的情况。

最终总结:

红锁的核心就是「多节点投票,过半生效」------ 用多个独立 Redis 节点代替单节点,通过「超过半数节点加锁成功」的规则,抵消单个节点宕机带来的锁失效问题,本质是用「性能和运维成本」换「更高的一致性」。用和红锁同款的「租房锁门」场景,把ZooKeeper分布式锁的核心逻辑讲得明明白白,保证比红锁还好懂:

Zookeeper

先定调:ZK锁的核心思路和红锁完全不同

红锁是「多把钥匙凑过半」,靠数量兜底;ZK锁是「排号进门+实时监控」,靠强一致性从根上避免问题------ZK天生就是为「分布式一致性」设计的,不像Redis是为「高性能」设计的。

用租房场景讲ZK锁的核心逻辑

还是租房锁门的例子,ZK就像一个「官方租房管理处」,规则特别严,所有租客都必须按它的规矩来:

第一步:管理处的「排号规则」(临时有序节点)

ZK里没有「钥匙」的概念,而是靠「排号单」管理:

  1. 所有想租房的租客(客户端),都要去管理处领一张「排号单」(在ZK的 /lock 节点下创建「临时有序子节点」,比如 lock-00000001、lock-00000002);
  2. 「临时」的意思:如果租客失联(客户端宕机/网络断了),排号单会自动作废(节点删除),不会占着位置;
  3. 「有序」的意思:管理处按租客来的顺序排号,先到的号小,后到的号大。
第二步:「号最小的才能锁门」(公平锁核心)
  1. 你领了排号单(比如 lock-00000001),然后去问管理处:「我是不是当前号最小的?」;
  2. 管理处说「是」,你就能锁门(加锁成功),其他人都得等着;
  3. 如果你的号不是最小的(比如是 lock-00000002),你就只能盯着前一个号的租客(lock-00000001),等他走了再说(监听前一个节点的删除事件)。
第三步:「走了必须销号」(解锁+实时通知)
  1. 你租完房走的时候,要去管理处销号(删除自己的节点),管理处会立刻通知下一个排号的租客(触发监听事件);
  2. 下一个租客收到通知后,再去问管理处「我是不是最小的?」,确认后就能锁门------全程只有一个租客能锁门。
第四步:「管理处宕机也不怕」(ZK的CP特性)

ZK本身也有主从,但和Redis不一样:

  1. Redis主从是「异步同步」(主节点锁门了,从节点可能还不知道);
  2. ZK主从是「同步同步」(主节点给你排号后,必须等所有从节点都记下来,才告诉你「排号成功」);
  3. 就算ZK主节点宕机,从节点升级为主,你的排号单还在,管理处的规则没变,不会出现「重复排号」的情况。

ZK锁为啥能解决Redis的一致性问题?

Redis锁的问题是「消息没同步就失联」,而ZK锁:

  1. 「临时节点」:客户端宕机自动销号,不会占着锁不放;
  2. 「同步一致性」:主节点的排号记录一定会同步给从节点,不会丢数据;
  3. 「排号+监听」:全程只有一个人能拿到锁,从根上保证互斥性。

ZK锁的缺点(还是租房举例)

  1. 慢一点:管理处要挨个排号、同步记录,比Redis「一把钥匙」的方式慢(性能不如Redis);
  2. 规则严:如果管理处(ZK集群)挂了一半以上节点,就彻底不能办业务了(CP模型,牺牲可用性换一致性);
  3. 略复杂:租客要排号、监听、确认,流程比直接拿钥匙繁琐(开发/运维成本比Redis高)。

核心总结(一句话)

ZK分布式锁的核心是「排号进门,实时监听,同步记账」------靠有序排队保证互斥,靠临时节点防死锁,靠同步一致性防数据丢失,天生解决Redis主从的锁失效问题,但代价是性能和可用性稍差。

相关推荐
懂点Tech7 小时前
ctfshow misc28:GIF 高度修改解题与脚本实现
开发语言·windows·python
comedate7 小时前
SMLib 的 Examples 导读:PyAPI / SM_API / SMLib 三组示例怎么读
python·cad·smlib·examples·sm_api
云和数据.ChenGuang7 小时前
Python 重写(Override)深度解析:从 MRO 到 super() 的完整机制
java·开发语言·人工智能·python·langchain·1024程序员节
摇滚侠7 小时前
《On Java 中文版 基础卷》阅读笔记 实现隐藏 12
java·数据库·笔记
川石课堂软件测试8 小时前
学习软件测试需掌握的一些知识
数据库·python·sql·功能测试·网络协议·mysql·http
万化冥合8 小时前
PyBox屏幕键盘如何辅助演示键盘操作?
python·计算机外设
车软学堂9 小时前
从测试转开发,到底要补什么
网络·人工智能·python·功能测试·单片机·车载系统·自动化
天空依然蔚蓝9 小时前
分享一个自动检测网站在线状态的python程序
python·运维开发·1024程序员节
路灯上の马陈9 小时前
二叉树的定义与性质
数据结构·二叉树·树结构·1024程序员节
岁月宁静9 小时前
一个 AI 项目从本地到上线,要经过哪些步骤?全流程讲清楚
python·docker·agent