--- tags: [test/review, architecture, arch/distributed, zookeeper-distributed-lock] create time: 2026-08-09 12:00 --- # ZooKeeper 分布式锁 — 测试题 ## 概述 本测试覆盖 ZooKeeper 分布式锁的核心机制,包括临时顺序节点创建、Watch 一次性触发、公平锁实现原理、ZAB 协议 CP 保证以及与 Redis 锁的系统级对比。共 10 道题目(6 选择 + 3 填空 + 1 简答)。 --- ## 一、选择题(6道,由浅入深) > **难度阶梯**: Q1-Q2 基础概念 → Q3-Q4 核心原理 → Q5-Q6 深入应用/边界场景 ### Q1(基础)— 考察定义层面 ZK 分布式锁中创建节点的类型是什么,使得客户端断开连接后能自动清理锁? A. PERSISTENT — 持久节点,需手动删除 B. EPHEMERAL_SEQUENTIAL — 临时顺序节点 C. PERSISTENT_SEQUENTIAL — 持久顺序节点 D. EPHEMERAL — 临时节点但无序号 ### Q2(基础)→ 以下关于 ZK Watch 机制的说法中,哪一个是正确的? A. Watch 被触发后会保持注册,持续监听后续变化 B. Watch 是一次性的(One-shot),触发后需要重新注册 C. Watch 只在 `getData` 调用时才会注册 D. Watch 事件通过数据读取通道推送,确保顺序性 ### Q3(进阶)— 核心原理 ZK 分布式锁天然实现了公平性,其根本原因是什么? A. Leader 节点按 FIFO 队列分配锁 B. 使用 SEQUENTIAL 序号决定锁的持有权,按序号大小排序 C. Watch 事件按时间戳排序后分发给等待者 D. ZAB 协议保证了写操作的原子性和有序性 ### Q4(进阶)— 比较/辨析 Redis 锁 vs ZK 锁在一致性模型上的主要区别是: A. Redis 和 ZK 都是 AP 系统 B. Redis 是 CP,ZK 是 AP C. Redis 单实例是 AP(Redlock 不确定),ZK 是 CP(ZAB 强一致) D. Redis 是 CP,ZK 是不确定的 ### Q5(深入)— 场景推理 N = 3 的 ZK 集群遭遇网络分区,左右各有一个节点。以下描述正确的是: A. 两边都能正常工作,各自选出新 Leader B. 左边可以继续写,右边拒绝服务 C. 都无法达成 Quorum,全部停止工作 D. 自动合并为 N=2 集群继续服务 ### Q6(深入)— 源码级/边界场景 ZK 会话超时默认 40 秒太长了。根据原文建议,会话超时应该设为多少?同时心跳间隔与会话超时的关系是什么? A. 建议 1~5 秒;heartbeat = timeout / 5 B. 建议 3~10 秒;heartbeat = timeout / 3 C. 建议 5~15 秒;heartbeat = timeout / 2 D. 建议 10~30 秒;heartbeat = timeout / 4 --- ## 二、填空题(3道) ### F1 — 填空1 ZK 分布式锁使用的事件类型是 _____,当子节点列表发生变化时,所有相关监听者都会收到通知。 > **提示**: 这个事件的英文命名直接表达了"节点子列表变化"的含义。 ### F2 — 填空2 ZAB 协议的第一个核心阶段是 _____,通过比较 ZXID(事务 ID)选出拥有最大 ZXID 的节点作为 Leader。第二个阶段是 Atomic Broadcast。 > **提示**: 回想 ZAB 的两个核心阶段名称。 ### F3 — 填空3 Curator 是 ZK 最流行的 Java 客户端,加锁成功后需要在 finally 块中调用 _____() 方法。该方法会递归释放所有重入计数,而不仅仅是一次 unlock。 > **提示**: Curator 的方法名不是简单的 unlock,而是表达"释放锁"的动作。 --- ## 三、简答题(1道) ### S1 某团队正在选型分布式锁方案,有人主张:"ZK 锁比 Redis 锁高级,我们应该用 ZK。"请结合原文内容,从以下几个维度给出你的分析并做出选型建议: - 一致性要求 - 性能需求 - 运维复杂度 - 业务场景匹配度 > **答题框架提示**: > 1. 先反驳"更高级就更好"的思维误区 > 2. 从三个维度客观对比 > 3. 给出具体场景下的推荐方案 --- ## 参考答案与解析 ### 选择题答案 | 题号 | 正确答案 | 解析 | |------|---------|------| | Q1 | B | EPHEMERAL_SEQUENTIAL = 临时 + 顺序。EPHEMERAL 语义保证 session 断开时自动清理,SEQUENTIAL 提供全局有序性。D 选项 EPHEMERAL 虽然也会自动清理,但没有序号就无法实现公平锁。 | | Q2 | B | Watch 是一次性的,触发后自动注销。客户端必须在接收到事件后立刻重新注册,否则可能永远不再收到下一次通知。 | | Q3 | B | 因为节点是 SEQUENTIAL 的,按序号大小决定锁的持有权——最小序号获得锁,其他节点按从小到大依次监听前一个节点。这是天然 FIFO 公平性。 | | Q4 | C | Redis 单实例是 AP(追求高可用),Redlock 的一致性甚至不确定;ZK 基于 ZAB 协议是 CP(追求强一致性),脑裂时宁可停服也不会出现两把锁同时存在。 | | Q5 | C | N=3 时 Quorum = 2。每个分区只有 1 个节点,无法达到半数(≥2),所以两个分区都无法工作。这是 CP 系统的必然结果——安全性优先于可用性。 | | Q6 | B | 建议设为 3~10 秒以更快感知宕机。但 heartbeat interval = timeout / 3,太短的 timeout 会导致心跳过于频繁增加网络开销。 | ### 填空题答案 | 题号 | 答案 | 解析 | |------|------|------| | F1 | `NodeChildrenChanged` | ZK 锁场景下关注的是子节点列表的变化。当上一个持有者删除节点后,下一个等待者的 watch 会收到 NODE_DELETED 事件进而 getChildren 重新竞争。 | | F2 | `Leader Election` | ZAB 的两阶段:① Leader Election 选举 Leader;② Atomic Broadcast Leader 广播 Proposal,Follower 回复 ACK 达到半数后提交。 | | F3 | `release` | Curator 的 InterProcessMutex.acquire() 支持重入,release() 会递归递减重入计数直到归零才真正发送删除请求。直接用 delete 会导致重入计数未释放。 | ### 简答题参考答案 S1:**参考答案要点**: 1. **"更高级"思维误区**:ZK 不是为"高级"设计的,而是为"强一致性协调"设计的。不要因为技术栈偏好而引入不必要的复杂度。 2. **一致性维度**:如果业务只需要简单互斥(如防止用户重复点击),Redis SET NX 足够好,CP 过度设计。如果需要 Leader 选举等强一致性保证,ZK 更适合。 3. **性能维度**:Redis 百万级 QPS(内存操作),ZK 需写事务日志同步复制,QPS 低一个数量级。高频短锁场景 Redis 明显更优。 4. **运维维度**:Redis 集群工具链成熟,ZK 需要维护奇数节点集群,运维成本高。 5. **结论**:简单互斥 → Redis + SET NX EX;强一致性少量并发控制(Leader 选举、Job 唯一绑定)→ ZK;不要为了"更高级"而上 ZK。 **评分标准**:答出任意 2 个要点即可得满分;完全正确需覆盖全部要点。 ## 关联笔记 - [[Redis 分布式锁]] - [[幂等设计方案]]