MultiLock 与 RedLock
Redisson 同时提供 MultiLock 和 RedLock API。源码上,RedLock 是在多个独立 RLock 上建立组合策略;它不是把单实例锁 magically 变成共识系统,工程上仍需明确 Redis 节点故障模型和业务可接受风险。
先给答案:Redisson 同时提供 MultiLock 和 RedLock API
Section titled “先给答案:Redisson 同时提供 MultiLock 和 RedLock API”Redisson 同时提供 MultiLock 和 RedLock API。源码上,RedLock 是在多个独立 RLock 上建立组合策略;它不是把单实例锁 magically 变成共识系统,工程上仍需明确 Redis 节点故障模型和业务可接受风险。 正文沿“组合结构 -> MultiLock 与 RedLock 的区别 -> 为什么不是简单 AND”展开:先确认入口和状态归属,再跟踪控制流或数据流的推进,最后落到对外可观察的结果。
主要失效边界集中在“RedLock 的争议核心不是 API 能否工作,而是它是否满足特定故障模型下的互斥保证”这些场景。它们破坏的是容量、顺序、并发或生命周期前提;排查时应先确认状态是否仍由正确对象持有,再核对推进条件和清理路径。
RedissonClient -> getLock(nameA), getLock(nameB), ... -> RedissonMultiLock / RedissonRedLock -> acquire each underlying lock -> rollback already acquired locks on failureRedisson#getMultiLock 位于 Redisson.java:689-694;RedissonRedLock 位于 RedissonRedLock.java:25-63,负责把多个锁传给组合实现。底层每把锁仍执行自己的 Hash + Lua + TTL 逻辑。
MultiLock 与 RedLock 的区别
Section titled “MultiLock 与 RedLock 的区别”| API | 目标 | 关键语义 |
|---|---|---|
MultiLock |
多个资源必须同时持有 | 任一失败通常触发已获锁的回滚 |
RedLock |
多个独立 Redis 实例上的多数派获取 | 以多数成功作为获取条件,并受时间窗口约束 |
单 RLock |
单 Redis 拓扑内互斥 | 依赖该 Redis 部署的可用性和故障转移 |
为什么不是简单 AND
Section titled “为什么不是简单 AND”替代方案:顺序获取全部锁,失败就返回。
为什么不行:已经获取的锁会泄漏,且不同客户端可能以不同顺序获取造成死锁。
证据:RedissonMultiLock 持有底层锁集合并实现失败后的释放路径;组合锁的正确性包含“回滚部分成功”而不只是成功条件。
RedLock 的争议核心不是 API 能否工作,而是它是否满足特定故障模型下的互斥保证。网络分区、长 GC、时钟和租约耗尽都可能使“多数派已获取”与业务实际执行时间脱节。对资金、库存等高价值临界区,建议配合 fencing token、幂等写入和数据库约束,而不是只依赖锁名。
| 场景 | 现象 | 原因 | 规避 |
|---|---|---|---|
| 节点延迟高 | 获取多数派但剩余有效时间很短 | 获取耗时挤压 lease window | 记录耗时并拒绝短租约 |
| 部分成功 | 少数锁仍残留 | 回滚也可能失败 | 后台清理、短 TTL、可重入幂等 |
| 业务执行超租约 | 两个客户端都进入临界区 | 锁已过期 | fencing token 或版本号校验 |
面试锚点
- MultiLock 和 RedLock 的目标有什么不同?
- 为什么组合锁必须有回滚?
- RedLock 为什么不能替代 fencing token?