服务端5月30日 20:13
Zookeeper 架构中 Leader、Follower 和 Observer 有什么区别?Zookeeper 是主从协同架构,但角色边界很清楚:Leader 负责写请求排序、事务提案和提交协调;Follower 负责本地读、转发写请求、参与选举和投票;Observer 只同步数据和服务读请求,不参与选举,也不计入写入多数派。设计重点不是所有节点都可写,而是用少量投票节点保证一致性,再用 Observer 扩展读能力。
## 追问
### 写请求怎么流转?
客户端连到 Follower 时,写请求会被转发给 Leader,由 Leader 生成事务提案并广播。超过半数 Follower ACK 后才提交。
### Observer 为什么能提升读性能?
Observer 不参加投票,增加它不会提高多数派门槛,也不会拖慢 Leader 等待 ACK 的路径。它适合承接跨机房或大规模客户端读流量。
### 为什么常用奇数个投票节点?
3 个节点能容忍 1 个故障,5 个能容忍 2 个。4 个投票节点也只能容忍 1 个故障,却多了同步和运维成本。
### 配置容易踩什么坑?
每台机器的 myid 必须和 server.X 对应。Observer 需要在节点配置里声明 peerType=observer,并在集群配置中标成 observer。
### 跨机房部署合适吗?
投票节点不建议跨高延迟机房,网络抖动会放大成选举和会话超时。远端读流量可考虑 Observer。标签
Zookeeper
Zookeeper是一种分布式协调服务,它提供了一组简单的原语,可以帮助开发人员构建分布式应用程序。Zookeeper的核心功能是管理和协调分布式应用程序中的进程,这些进程需要协调访问共享资源或协调执行任务。Zookeeper通过维护一个分层命名空间和状态树来实现这一点,应用程序可以向Zookeeper注册自己的状态,其他应用程序可以在Zookeeper上监听这些状态。Zookeeper还提供了一些其他的功能,如分布式锁和队列,以帮助开发人员构建高可用性、可伸缩性和可靠性的分布式系统。Zookeeper通常与Hadoop、Kafka和其他分布式系统一起使用。

服务端5月30日 20:13
Zookeeper Leader 选举机制是怎样工作的?Zookeeper 的 Leader 选举不是谁先启动谁当 Leader,而是看哪个节点最适合承接已提交历史。Fast Leader Election 会在 LOOKING 状态下交换投票,每张票通常包含 epoch、zxid 和 sid:先比较选举轮次,再看 zxid 谁更新,zxid 相同才比较 sid。某个候选者拿到超过半数投票后成为 Leader。
## 追问
### Leader 选举什么时候触发?
集群首次启动、Leader 宕机、网络分区导致多数 Follower 失联时,节点都会进入 LOOKING。短暂 GC、磁盘卡顿也可能让 Follower 误判超时。
### zxid 和 sid 谁更重要?
zxid 更重要,因为它代表节点看到的事务进度。只有 zxid 一样时才比较 sid,sid 大只是为了打破平票。
### 为什么必须超过半数才能当选?
多数派机制保证任意两个成功多数集合一定有交集,新 Leader 能接触到上一任已提交事务信息。
### 选举期间客户端会怎样?
写请求通常会失败、阻塞或连接断开,需要客户端重试。业务侧要设置合理 sessionTimeout 和重试退避。
### 排查选举问题看什么?
先确认 myid 和 zoo.cfg 的 server.X 是否对应,再检查 2888/3888 端口。日志里的 LEADING、FOLLOWING、Cannot open channel 很关键。服务端5月30日 20:13
Zookeeper 如何通过 ZAB 协议保证数据一致性?Zookeeper 的一致性主要靠 ZAB 协议保证。所有写请求最终交给 Leader 排序,Leader 分配全局递增的 zxid,再把提案广播给 Follower;超过半数节点 ACK 后,事务才提交。代价是写入要等多数派,延迟不会像单机缓存那样低;好处是 Leader 宕机后,新 Leader 能根据 zxid 找到较完整的提交历史,避免已提交数据丢失或未提交数据乱入。
## 追问
### ZAB 和普通主从复制最大区别是什么?
普通主从复制常见问题是主节点确认太早,故障时从节点未必拥有同一批数据。ZAB 要求事务拿到多数派 ACK 再提交。
### zxid 为什么能决定数据新旧?
zxid 是事务全局序号,高位通常关联 Leader epoch,低位表示任期内事务递增。选主和同步时比较 zxid 判断谁更新。
### 读请求为什么不一定强一致?
Follower 和 Observer 异步接收提交消息,可能比 Leader 慢。必须读最新时可以先执行 sync(),但有协调成本。
### Leader 崩溃时怎么避免事务丢失?
新 Leader 会和其他节点对齐事务日志:落后的补发 DIFF,差太多的发 SNAP,未提交尾巴会 TRUNC 回滚。
### 怎么判断一致性问题来自哪里?
先确认节点角色和存活,再看日志里的 zxid、leader election、syncLimit 超时。很多读旧值只是连到了落后 Follower。服务端5月30日 20:13
Zookeeper 性能怎么优化?哪些参数最容易踩坑?Zookeeper 性能优化先分清读多、写多还是连接多。读多可以加 Observer 或让客户端分散到 Follower;写多瓶颈通常在 Leader、事务日志 fsync 和过半确认;连接多、Watcher 多、znode 大,会把内存和网络打满。有效优化不是把参数调大,而是减少无意义写入、控制节点大小、把事务日志放到稳定低延迟磁盘。
## 追问
### 加节点一定能提升性能吗?
不一定。Follower 或 Observer 能分担读请求,但写请求仍要 Leader 发起并等待过半确认,投票节点越多,写入链路可能越长。
### dataDir 和 dataLogDir 为什么分开?
事务日志每次写入都很敏感,最好放低延迟 SSD 或独立盘;快照体积大但频率低,可以放普通数据盘。
### Watcher 多会带来什么问题?
Watcher 会占服务端内存,事件触发时还会产生通知风暴。客户端重连后无脑重复注册,会导致 watch_count 持续上涨。
### 单个 znode 为什么不建议放大数据?
Zookeeper 是协调元数据系统,不是文件存储。大节点会放大网络传输、序列化、快照和事务日志成本。
### 性能压测看哪些边界?
至少分读密集、写密集、混合读写、重连风暴和 Watcher 触发场景。每次只改一个参数,记录 P95/P99、磁盘 await、GC pause。
## 写段配置
```properties
tickTime=2000
initLimit=10
syncLimit=5
maxClientCnxns=100
dataLogDir=/data/zookeeper/txnlog
autopurge.purgeInterval=1
```服务端5月30日 20:13
Zookeeper、Etcd 和 Consul 有什么区别?该怎么选?Zookeeper、Etcd 和 Consul 都能做分布式协调,但出发点不一样。Zookeeper 更像协调原语库,擅长临时节点、顺序节点、Watcher、分布式锁和老牌 Java/大数据生态;Etcd 是强一致 KV,Raft、revision、租约和 Watch 更贴近 Kubernetes 控制面;Consul 把服务发现、健康检查、多数据中心和 KV 打包在一起,适合微服务治理。
## 追问
### Consul 是 AP 还是 CP?
不能简单说 Consul 全部是 AP。服务发现依赖 Gossip,读到的信息可能短暂滞后;Server 集群和 KV 一致读依赖 Raft,更接近 CP。
### Zookeeper 和 Etcd 的 Watch 有什么差别?
Zookeeper 的 Watch 是一次性通知,触发后需要重新注册。Etcd Watch 基于 revision,可以从指定版本继续消费事件,但要处理 compaction 后版本过旧的问题。
### 为什么 Kubernetes 选 Etcd?
Etcd 的 Raft KV、revision、租约和 gRPC API 更符合 Kubernetes 的对象存储与控制循环模型。Zookeeper 数据模型更偏传统中间件生态。
### 老系统要不要迁到 Etcd?
如果只是为了技术更新,通常不值得。临时节点、顺序节点、ACL、Watcher 语义都要重做,只有控制面重构时才值得评估。
### 三者性能怎么比较才靠谱?
按读写比例、值大小、Watcher 数量、磁盘 fsync 和网络延迟压测。不要只看单机 benchmark。服务端5月30日 20:13
Zookeeper 连接超时、脑裂和数据不一致怎么排查?Zookeeper 出问题时不要先调参数,先判断是客户端、网络、磁盘还是集群选举问题。连接超时通常看 sessionTimeout、端口连通性和服务端负载;脑裂要看是否真的出现多个可写 Leader,多数情况下是网络分区或监控误判;数据不一致多半是读到了落后的 Follower,需要用 sync() 或改读 Leader。
## 追问
### 连接超时一定是服务端问题吗?
不一定。先用 nc 验证 2181 端口,再看客户端 DNS、负载均衡、防火墙和连接池是否耗尽。服务端 latency_max 很高时,还要查磁盘 I/O、GC 暂停和 outstanding 请求堆积。
### Zookeeper 会不会真的脑裂?
Zookeeper 依赖过半机制,正常配置下不会允许两个 Leader 同时提交事务。危险点通常是偶数节点、跨机房高延迟部署、错误 myid/server 配置或监控误判。
### 数据不一致时 sync() 为什么有用?
Follower 读可能落后于 Leader,sync(path) 会让当前连接先同步到较新的事务点。代价是多一次网络往返,强一致读路径不要滥用。
### Watcher 泄漏怎么判断?
看 `echo wchs | nc zk1 2181` 和客户端注册逻辑。很多泄漏来自异常重试时重复注册,修复时要让 Watcher 与业务对象生命周期绑定。
### 故障恢复最怕什么?
最怕只恢复快照不恢复事务日志,或不同节点混用不同版本数据目录。恢复前先停集群、备份现状,再按 zxid 最新且完整的快照和日志恢复。
## 写段命令
```bash
echo ruok | nc zk1 2181
echo stat | nc zk1 2181
echo mntr | nc zk1 2181 | egrep 'latency|connections|outstanding|synced'
```服务端5月30日 19:58
Zookeeper 运维监控要看哪些指标和告警?Zookeeper 运维的重点不是“进程活着就行”,而是确认多数派健康、写入延迟可控、客户端连接没有失控。日常先看四类指标:集群角色和节点存活、请求延迟、连接与 Watcher 数量、磁盘和 JVM 状态。`stat` 能看 leader/follower,`mntr` 适合接 Prometheus exporter,`cons` 能排查连接来源,`wchs` 可以判断 Watcher 是否异常膨胀。
## 追问
### 线上最应该优先盯哪个指标?
优先看 `zk_avg_latency`、`zk_max_latency` 和 `zk_outstanding_requests`。节点存活重要,但很多事故在节点没挂前,延迟和排队已经先报警了。
### Watcher 数量突然升高说明什么?
通常说明客户端重复注册、服务实例目录过大,或某个配置监听没有去重。短期定位来源连接,长期要改客户端代码。
### Zookeeper 磁盘满了会怎样?
常见表现是写入失败、延迟飙升、Leader 不稳定,严重时节点无法启动。要开启 autopurge,并监控 dataDir 和 dataLogDir。
### 滚动重启为什么不能一口气重启多台?
Zookeeper 需要多数派可用,5 节点同时停 3 台就失去法定人数。稳妥做法是一台一台重启并确认状态。
## 写段命令
```bash
echo stat | nc zk1 2181
echo mntr | nc zk1 2181 | egrep 'latency|outstanding|watch_count'
echo cons | nc zk1 2181 | wc -l
```服务端5月30日 19:58
Zookeeper 架构和数据模型该怎么设计才稳?Zookeeper 要稳,先别把它当数据库用,而要当成“小而关键的协调层”。生产集群通常选 3 或 5 个投票节点:3 节点能容忍 1 台故障,5 节点能容忍 2 台故障;节点数不是越多越好,写入要多数派确认,7 台以上会增加选举和同步成本。部署时尽量跨机架或可用区,但不要把网络延迟拉得太大。
## 追问
### 为什么生产集群常用 3 或 5 个节点?
Zookeeper 依赖多数派,4 个节点仍然只能容忍 1 台故障,因为多数派需要 3 票。偶数节点增加机器和同步成本,却不提升容错收益。
### dataDir 和 dataLogDir 为什么建议分开?
事务日志是写请求关键路径,磁盘抖动会直接放大写延迟。快照文件更偏后台持久化,和日志分盘更稳。
### Zookeeper 适合存业务大数据吗?
不适合,它适合配置、状态、锁节点、服务实例这类小数据。大对象会增加网络复制、快照体积和恢复时间。
### Watcher 最容易踩什么坑?
原生 Watcher 触发一次就失效,收到事件后要重新注册。回调里不要做重活,应投递异步任务。
### 分布式锁一定要自己实现吗?
不建议,Curator 的 InterProcessMutex 已处理大量边界。业务侧更应该关注超时时间、finally 释放锁和锁粒度。
## 写段配置
```properties
tickTime=2000
initLimit=10
syncLimit=5
dataDir=/data/zookeeper/data
dataLogDir=/data/zookeeper/logs
autopurge.purgeInterval=1
```服务端5月27日 21:35
Zookeeper 版本演进有哪些关键节点?升级怎么做?## 核心答案
ZooKeeper 从 2008 年开源至今,真正值得关注的版本节点只有几个:
- **3.3.x** 引入 Observer 角色,横向扩展读能力不拖慢写吞吐;
- **3.4.x** 剔除 UDP 选举,只保留 TCP 版 FastLeaderElection,部署最广的稳定版;
- **3.5.x** 新增容器节点(无子节点自动删除)、TTL 节点、动态 reconfig(不停机增减节点),从这版起支持在线扩缩容;
- **3.6.x** 支持 7 种节点类型,TLS 加密传输,内存和日志预分配优化;
- **3.8.x** 默认开启安全配置,增强容器化/K8s 适配。
版本选择:新项目直接 3.8.x;老集群跑 3.4.x 且稳定、无动态扩容需求就不必急着升。
## 升级怎么做
滚动升级是标准做法——逐台停 follower、换包、重启,最后 leader 切换后再升原 leader。存活节点过半集群就可用。跨大版本需分步走:3.4 → 3.5 → 3.6 → 目标版本,不能跳级。升级前备份 dataDir 和事务日志,3.4.x 老集群可能只有日志没快照,首次启动新版会全量回放,耗时较长。
## 追问
**Observer 和 Follower 的区别?** Observer 不参与投票和写请求过半确认,只异步同步数据并处理读请求,适合跨机房或读多写少场景。
**3.5 的动态 reconfig 有什么坑?** reconfig 是原子操作,但新旧节点网络不通或 myid 冲突时集群会卡在选举状态。先在测试环境验证,生产操作时保留回滚配置。
**KRaft 会取代 ZK 吗?** Kafka KRaft 已移除 ZK 依赖,但 ZK 仍被 Dubbo、HBase 等广泛使用。短期不会淘汰,新项目可考虑 KRaft 版 Kafka 减少运维组件。服务端5月27日 21:31
Zookeeper 是什么?它有哪些核心特性和应用场景?## Zookeeper 是什么?它有哪些核心特性和应用场景?\n\nZookeeper 是 Apache 维护的开源分布式协调服务,通过层次化命名空间和 Watcher 机制,为分布式应用提供配置管理、服务发现、分布式锁等协调能力。它本质上是一个高可用的分布式小文件存储系统,读多写少,适合做"共识"而非"存储"。\n\n## 核心特性\n\n**一致性保证**:所有客户端看到的数据视图一致,事务请求按顺序严格执行,要么全部成功要么全部失败。\n\n**高可用**:集群部署(通常3/5/7节点),过半节点存活即可服务。Leader 处理写请求并通过 ZAB 协议同步到 Follower,Follower 处理读请求,Observer 扩展读性能但不参与选举。\n\n**Watcher 机制**:客户端可对节点注册监听,数据变更时服务端主动推送通知。这是实现配置动态更新、服务上下线感知的基础。注意 Watcher 是一次性的,触发后需重新注册。\n\n## 数据模型\n\nZookeeper 采用树形结构,每个节点称为 ZNode。四类节点:\n\n- **持久节点**:创建后永久存在,除非显式删除\n- **临时节点**:绑定会话,断连自动删除——这是服务注册和分布式锁的实现基础\n- **持久顺序节点**:自动追加递增序号,用于分布式队列\n- **临时顺序节点**:临时+顺序,分布式锁的公平实现方式\n\n每个 ZNode 维护 dataVersion(数据版本)、cversion(子节点版本)、aversion(ACL版本),实现乐观锁。\n\n## 典型应用场景\n\n- **配置中心**:节点存配置,Watcher 监听变更,实现动态推送\n- **服务注册与发现**:服务启动时写临时节点,宕机自动摘除\n- **分布式锁**:临时顺序节点实现公平锁,避免羊群效应\n- **Leader 选举**:利用临时顺序节点,序号最小的节点成为 Leader\n\n## 追问\n\n**ZAB 协议和 Paxos 的区别?** ZAB 专为 Zookeeper 设计,支持崩溃恢复和消息广播两种模式,强调主备切换时的数据一致性;Paxos 是通用一致性算法,ZAB 可视为其简化变体,在 Leader 选举效率上更优。\n\n**临时节点在什么情况下不会立即删除?** 会话超时而非连接断开时触发删除。网络抖动期间客户端可能在其他 Server 上重建会话,此时临时节点迁移而非删除。服务端5月27日 21:28
Zookeeper 的 Watcher、ACL 和事务操作怎么用?## Watcher、ACL 和事务操作是 ZooKeeper 的三大高级特性
Watcher 是一次性的:触发后自动失效,必须在回调中重新注册,否则会丢事件。注册方式有三种——getData 监听数据变化、getChildren 监听子节点变化、exists 监听节点创建。常见坑:客户端串行执行回调,回调里不能做耗时操作,否则阻塞后续事件处理。
ACL 控制"谁能对哪个节点做什么"。权限分 CREATE/READ/WRITE/DELETE/ADMIN 五种,方案有 world(开放)、auth(认证用户)、digest(用户名密码)、ip(地址段)。生产建议:关键路径用 digest 方案收紧权限,避免 world:anyone 的 OPEN_ACL_UNSAFE。
事务操作通过 multi 接口实现,将多个操作打包原子提交。底层依赖 zxid 保证顺序一致性——zxid 高 32 位是 Leader 周期号,低 32 位递增计数。multi 全部成功或全部失败,不存在部分执行。典型场景:同时创建多个互相关联的节点。
**追问:Watcher 为什么设计成一次性?** 服务端为每个节点维护 Watcher 集合,一次性触发后即清理,避免海量长连接下内存膨胀。代价是客户端必须重注册,Curator 的 Cache 机制封装了这个逻辑。
**追问:ACL 和 Linux 文件权限有什么区别?** ACL 是三元组 scheme:id:perm,scheme 决定认证方式而非简单的用户组。同一个节点可以叠加多条 ACL,粒度到操作类型而非读写两位。
**追问:multi 操作中某一步失败会怎样?** 服务端预校验所有操作,任一失败则整体回滚,已执行的操作也会撤销。这是 ZAB 协议两阶段提交在客户端侧的体现。服务端5月27日 21:25
Zookeeper 有哪些典型的应用场景?如何实现分布式锁和服务注册发现?## 核心场景与原理
Zookeeper 的典型应用场景本质是对三大能力的组合:**临时节点**(会话结束自动删除)、**顺序节点**(自带递增编号)、**Watcher 机制**(变更实时通知)。
**分布式锁**是面试追问最多的场景。实现方式:客户端在 `/lock` 下创建临时顺序节点,获取所有子节点后判断自己是否序号最小——最小则持锁,否则 Watch 前一个节点。释放时删除自身节点即可,会话断开临时节点也会自动清除,不会死锁。监听前序节点而非所有节点,是为了避免"羊群效应"。
**服务注册与发现**依赖临时节点 + Watch。服务上线创建临时节点注册地址,消费者 Watch 该目录获取实例列表。提供者宕机后节点自动消失,消费者收到通知更新列表。Dubbo 早期即用此方式做服务治理。
**配置中心**将配置写入持久节点,客户端 Watch 变更,改动实时推送,适合读多写少的强一致性场景。
**Master 选举**同样借助顺序节点——参与者各创建临时顺序节点,序号最小者成为 Master,其余 Watch 前序节点,故障时自动重选。Kafka Controller 选举便用此方式。
此外还有命名服务(顺序节点生成全局唯一 ID)、分布式队列(FIFO 与 Barrier 两种模型)、集群管理(临时节点感知成员上下线)。
## 生产实践要点
ZooKeeper 适合强一致性、读多写少、数据量小的协调场景,不适合海量存储或高并发写入。Kafka、HBase 仍依赖 ZK 做元数据管理和选举,但新系统更多选择 Nacos(注册+配置一体)、etcd(更轻量)等替代。
ZK 分布式锁比 Redis 锁更可靠——CP 模型保证主从切换不丢锁;代价是性能更低。金融等对锁可靠性要求高的场景优先选 ZK。
## 追问方向
- Watch 是一次性的,触发后须重新注册,通知有延迟,如何保证不丢事件?
- 临时顺序节点创建和序号判断之间网络分区会发生什么?
- ZK 集群 Leader 选举过程中能否对外提供服务?