日期:2026-07-11
标签:#面试 #八股 #后端 #系统设计 #场景题
一句话答案
常见实现包括数据库唯一约束、Redis SET NX PX 和 ZooKeeper/etcd 临时节点;选择取决于一致性要求、性能和故障容忍度。
对比
| 方案 | 核心机制 | 优点 | 局限 |
|---|---|---|---|
| 数据库 | 唯一索引/条件更新 | 简单、一致性边界清晰 | 性能较低,需处理锁记录过期 |
| Redis | SET key value NX PX | 性能高、实现方便 | 主从切换和租约过期可能带来并发持锁 |
| ZooKeeper/etcd | 临时节点、租约、Revision | 一致性强、支持监听和选主 | 运维及调用成本更高 |
Redis 实现要点
- 加锁:随机唯一 value,单命令设置 NX 和过期时间。
- 解锁:Lua 脚本比较 value 后删除,避免删掉别人的锁。
- 长任务:看门狗续租,但必须设置最大持有时长和异常退出策略。
- 关键写操作:增加 fencing token,下游拒绝过期持有者。
常见错误说法
- 错误:先
SETNX,再单独EXPIRE。两条命令间宕机会留下死锁。 - 错误:解锁直接
DEL。锁过期后可能删除新持有者的锁。 - 错误:有 TTL 就绝对安全。长暂停、网络分区和主从切换仍需考虑。
面试官追问
- Redlock 有哪些争议?
- 可重入锁怎么实现?
- 公平锁如何实现?
- 锁续期时进程失联怎么办?
面试官追问参考答案
1. Redlock 有哪些争议?
争议核心是它依赖多个独立 Redis 实例、时钟和租约假设,在长暂停、网络延迟和故障恢复下仍可能出现两个客户端都认为持锁。对正确性要求高的场景,仅有租约不够,应使用共识系统并配合 fencing token;Redlock 更适合能容忍极小冲突概率的效率型锁。
2. 可重入锁怎么实现?
锁 value 记录持有者唯一标识和重入计数。同一持有者再次加锁时原子增加计数并续期,解锁时递减,减到零才删除;Redis 中应用 Lua 保证检查和修改原子性。持有者标识通常包含实例、线程和请求上下文。
3. 公平锁如何实现?
为等待者维护按到达顺序排列的队列,例如使用 ZooKeeper 临时顺序节点,只有最小节点获得锁,其他节点监听前驱。Redis 可用队列加通知实现,但要处理等待者超时、进程死亡、队首清理和惊群,复杂度明显更高。
4. 锁续期时进程失联怎么办?
租约 TTL 保证失联后最终自动释放;看门狗只能在进程健康且仍是持有者时续期。续期失败必须停止业务并禁止继续写,关键资源由 fencing token 兜底;不能因为网络恢复就沿用旧锁。