vault backup: 2026-08-09 19:06:40

This commit is contained in:
2026-08-09 19:06:40 +08:00
parent e2975eb86b
commit 9d664545c9
46 changed files with 7287 additions and 0 deletions
@@ -0,0 +1,146 @@
---
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 分布式锁]]
- [[幂等设计方案]]