分布式协调服务
分布式协调服务 #
Zookeeper、etcd、Consul 三大分布式协调服务对比与应用
📋 目录 #
核心概念 #
什么是分布式协调服务 #
核心作用:
| 功能 | 说明 | 典型场景 |
|---|---|---|
| 配置中心 | 集中存储配置,实时推送 | Spring Cloud Config、Apollo |
| 服务发现 | 服务注册与发现 | 微服务架构 |
| 分布式锁 | 跨进程互斥锁 | 限流、秒杀 |
| Leader选举 | 集群Leader选举 | Kafka、HBase |
| 集群管理 | 节点状态监控 | 负载均衡 |
Zookeeper #
经典分布式协调服务 ⭐⭐⭐⭐⭐
核心特性 #
Zookeeper = 文件系统 + 通知机制
数据模型 (类似文件系统):
节点类型:
- 持久节点: 一直存在
- 临时节点: 客户端断开即删除
- 顺序节点: 自动追加序号
- 临时顺序节点: (用于分布式锁)
ZAB 协议 #
ZAB (ZooKeeper Atomic Broadcast)
两种模式:
1. 恢复模式 (崩溃恢复)
- Leader选举
- 数据同步
- 保证数据一致性
2. 广播模式 (消息广播)
- Leader接收写请求
- 广播给Follower
- 过半ACK后提交
典型应用 #
1. 分布式锁 #
// 实现思路
1. 创建临时顺序节点
2. 获取所有子节点,判断是否是最小的
3. 如果是最小,获取锁
4. 否则,监听前一个节点的删除事件
5. 业务执行完毕,删除节点
2. 服务发现 #
注册: 服务启动时创建临时节点
/services/order-service/node-1 (临时节点)
发现: 客户端监听 /services/order-service
- 新节点加入: 触发NodeChildrenChanged
- 节点下线: 临时节点自动删除
3. 配置中心 #
1. 配置存储在持久节点
/config/database.url = "jdbc:mysql://..."
2. Watch机制监听配置变化
watch /config/database.url
3. 配置更新触发回调
- 客户端收到事件
- 重新加载配置
配置参数 #
tickTime=2000 # 心跳间隔(毫秒)
initLimit=10 # 初始同步超时(10*tickTime)
syncLimit=5 # 同步请求超时
dataDir=/var/lib/zookeeper # 数据目录
clientPort=2181 # 客户端端口
maxClientCnxns=60 # 最大客户端连接数
autopurge.snapRetainCount=3 # 保留快照数量
autopurge.purgeInterval=1 # 自动清理间隔(小时)
etcd #
Kubernetes核心组件 ⭐⭐⭐⭐⭐
核心特性 #
etcd = 键值存储 + RPC
数据模型:
-扁平键值对 (不支持目录树)
- 支持版本、租约、事务
典型命令:
PUT /name "tom" # 设置值
GET /name # 获取值
DEL /name # 删除
WATCH /name # 监听变化
Raft 协议 #
etcd基于Raft协议保证一致性
核心概念:
- Term: 选举任期
- Log: 操作日志
- Leader: 负责处理写请求
- Follower: 复制Leader日志
- Candidate: 候选Leader
流程:
1. Leader接收写请求追加日志
2. 并发复制到Follower
3. 收到多数派ACK后提交
4. 返回客户端成功
核心API #
# 设置键值
ETCDCTL_API=3 etcdctl put /config/database.url "jdbc:mysql://..."
# 获取值
etcdctl get /config/database.url
# 监听变化
etcdctl watch /config/database.url
# 租约: 设置带过期的键
etcdctl put --lease=5s /session/lock "node-1"
# 分布式锁: 使用租约 + 事务
etcdctl txn \
--interactive
# 获取所有键
etcdctl get / --prefix
# 读取历史上某个版本的值
etcdctl get /config --rev 10
典型应用 #
1. Kubernetes 核心组件 #
etcd存储:
- 节点信息 (/registry/nodes/...)
- Pod信息 (/registry/pods/...)
- Service信息 (/registry/services/...)
- ConfigMap & Secret
- Deployment状态
K8s组件:
- API Server: 读写etcd
- Scheduler: 读取调度
- Controller: 监听变化
- Kubelet: 上报状态
2. 分布式锁 #
// etcd分布式锁实现
// 1. 创建租约
lease := client.Grant(60).LeaseID()
// 2. 事务: 成功解锁则设置key
txn := client.Txn(context.Background())
txn.If(
cmp.Key(lockKey).Equals(cmp.CompareResult("0")) // 键不存在
).Then(
client.OpPut(lockKey, value, client.WithLease(lease)), // 设置值
)
// 3. 维持租约 (keepalive)
ch, _ := client.KeepAlive(context.Background(), lease)
// 4. 释放锁
client.Revoke(lease)
3. 配置中心 #
优势:
- 高性能: QPS可达10万+
- 强一致性: Raft保证
- Watch实时: 配置变更立马通知
实现:
- 配置存储在etcd
- 应用启动拉取配置
- Watch监听变化
- 变更通知自动热更新
Consul #
服务网格与配置中心 ⭐⭐⭐⭐
核心特性 #
功能矩阵:
- 服务发现
- 健康检查
- KV存储
- 多数据中心
- Service Mesh (Connect)
- ACL安全
架构组件 #
Client Agent:
- 服务注册
- 健康检查
- 转发请求
Server Agent:
- Raft共识
- 数据存储
- 领导者选举
服务注册与发现 #
# 注册服务
consul services register \
-id="web" \
-name="web" \
-port=8080 \
-address="192.168.1.100" \
-check=tcp://localhost:8080/interval=10s
# 查询服务
consul catalog services
# 健康检查
consul healthchecks service web
# 服务发现 (DNS)
dig @127.0.0.1 -p 8600 web.service.consul
# 服务发现 (HTTP)
curl http://localhost:8500/v1/catalog/service/web
KV存储 #
# 设置值
consul kv put /config/database.url "jdbc:mysql://..."
# 获取值
consul kv get /config/database.url
# 监听变化
consul kv watch /config/database.url
# 递归获取所有键
consul kv get -recurse /
选型指南 #
对比表格 #
| 特性 | Zookeeper | etcd | Consul |
|---|---|---|---|
| 一致性模型 | ZAB | Raft | Raft |
| 数据模型 | 层级目录 | K-V | K-V |
| 服务发现 | 需要自行实现 | ✅ 支持 | ✅ 原生支持 |
| 健康检查 | 基础 | 基础 | 丰富(多种检查方式) |
| 多数据中心 | 需要自行实现 | 需要自行实现 | ✅ 原生支持 |
| API接口 | 专用 | HTTP/gRPC | HTTP/DNS |
| 性能 | 中 | 高 | 中 |
| 复杂度 | 高 | 中 | 低 |
| 社区活跃度 | 下降 | 极高(K8s) | 高 |
选型建议 #
选择 Zookeeper:
- Hadoop生态 (HBase、Kafka 旧版本)
- Java项目需要分布式锁
- 团队熟悉
选择 etcd:
- Kubernetes环境
- 需要高性能K-V存储
- 云原生应用
- Go项目
选择 Consul:
- 服务网格
- 多数据中心
- 需要丰富健康检查
- DevOps友好
选择配置中心:
- Spring Cloud → Nacos
- 大型公司 → Apollo
场景对比 #
| 场景 | 推荐 | 原因 |
|---|---|---|
| Spring Cloud | Nacos | 原生支持,注册配置中心 |
| Kubernetes | etcd | 核心依赖 |
| 大数据 | Zookeeper | 生态集成好 |
| 微服务 | Consul/Nacos | 服务发现方便 |
| Go项目 | etcd | 原生支持 |
面试题汇总 #
Zookeeper篇 #
- ZAB协议原理?
- Zookeeper数据模型?
- 如何实现分布式锁?
- Watch机制如何工作?
- Leader选举过程?
etcd篇 #
- Raft协议在etcd中的应用?
- etcd的应用场景?
- 如何实现分布式锁?
- etcd的Watch机制?
- etcd为什么适合Kubernetes?
Consul篇 #
- Consul的核心功能?
- 服务注册与发现流程?
- 健康检查方式有哪些?
- Consul多数据中心如何部署?
对比篇 #
- Zookeeper vs etcd vs Consul?
- 不同场景如何选型?
- 配置中心如何选择?
面试题答案详解 #
Zookeeper篇 #
- ZAB协议原理?
答案:
ZAB = ZooKeeper Atomic Broadcast
两种模式:
- 崩溃恢复: 选主+数据同步
- 消息广播: 类似2PC,过半ACK提交
- Zookeeper数据模型?
答案:
类似文件系统的树形结构:
四种节点类型:
| 类型 | 说明 |
|---|---|
| Persistent | 持久节点,一直存在 |
| Ephemeral | 临时节点,会话结束删除 |
| Persistent Sequential | 持久顺序 |
| Ephemeral Sequential | 临时顺序 |
- 如何实现分布式锁?
答案:
步骤:
- 创建临时顺序节点
/locks/node-00000001 - 获取所有子节点,检查自己是不是最小
- 如果是最小,获取锁
- 如果不是,监听前一个节点
- 前一个节点删除,再检查
为什么用临时顺序节点?
- 临时:宕机自动释放锁,防死锁
- 顺序:避免惊群,公平
- Watch机制如何工作?
答案:
特性:
- 单次触发(触发一次就失效)
- 事件监听(节点创建/删除/数据变更)
- 异步通知
典型应用:
- 服务发现:监听子节点变更
- 配置中心:监听配置变更
- 分布式锁:监听前一个节点
- Leader选举过程?
答案:
选举触发条件:
- 服务器启动
- Leader挂了
- 与Leader断开
过程:
- 所有Server投票给自己(ZXID最大、myid
- 过半票多当选
- 超过半数同意
- 新Leader同步数据
etcd篇 #
- Raft协议在etcd中的应用?
答案:
Raft三个角色:
| 角色 | 说明 |
|---|---|
| Leader | 接收客户端请求 |
| Candidate | 竞选Leader |
| Follower | 跟随者,处理日志 |
Raft流程:
- 选举:心跳超时 → 投票 → 选主
- 日志复制:Leader写日志 → Follower同步 → 过半ACK → 提交
- etcd的应用场景?
答案:
| 场景 | 说明 |
|---|---|
| 服务注册发现 | Kubernetes核心 |
| 配置中心 | 热更新配置 |
| 分布式锁 | Lease + Transaction |
| 选主 | Leader选举 |
| 队列 | 有序消息队列 |
- 如何实现分布式锁?
答案:
方案1: Lease + Transaction + Watch
- Create Lease(TTL)
- Create Key(附带Lease)
- If createTransaction保证原子操作)
- etcd的Watch机制?
答案:
与Zookeeper不同:
- 持续Watch,不是单次
- 支持历史版本号
- 支持Prefix
**gRPC stream长连接
- etcd为什么适合Kubernetes?
答案:
| 特性 | 说明 |
|---|---|
| 强一致性 | Raft保证 |
| WATCH | 实时通知 |
| 高性能 | 10万+ QPS |
| 精简API | REST/gRPC |
| 历史版本 | 回滚 |
| Compact | 压缩 |
Consul篇 #
- Consul的核心功能?
答案:
| 功能 | 说明 |
|---|---|
| 服务注册发现 | HTTP/DNS |
| 健康检查 | TCP/HTTP/TTL |
| KV存储 | 配置中心 |
| 多数据中心 | 跨机房 |
| Service Mesh | Connect |
- 服务注册与发现流程?
答案:
- 服务启动,注册到Consul
- 健康检查
- 客户端查询服务列表
- 健康检查方式有哪些?
答案:
| 方式 | 说明 |
|---|---|
| TCP | 连接指定端口 |
| HTTP | HTTP返回200 |
| Script | 执行脚本 |
| TTL | 定期心跳 |
| gRPC | gRPC健康检查 |
- Consul多数据中心如何部署?
答案:
- Gossip协议跨DC通信
- 跨DC查询转发
- 多DC配置同步
对比篇 #
- Zookeeper vs etcd vs Consul?
答案:
| 对比 | Zookeeper | etcd | Consul |
|---|---|---|---|
| 协议 | ZAB | Raft | Raft |
| CAP | CP | CP | CP |
| 服务发现 | 需自行实现 | 需自行实现 | 原生 |
| 健康检查 | 简单 | 简单 | 丰富 |
| 多数据中心 | ❌ | ❌ | ✅ |
| API | 自定义 | HTTP/gRPC | HTTP/DNS |
| K8s | ❌ | ✅核心 | ❌ |
- 不同场景如何选型?
答案:
| 场景 | 推荐 |
|---|---|
| Kubernetes | etcd |
| Spring Cloud | Nacos |
| **Consul | 多数据中心 |
| 大数据 | Zookeeper |
| **注册+配置中心 | Nacos |
- 配置中心如何选择?
答案:
| 配置中心 | 优点 | 缺点 |
|---|---|---|
| Nacos | SpringCloud官方 | 较新 |
| Apollo | 完善 | 重量级 |
| Consul | 多数据中心 | 国内少 |
| etcd | 简单 | 功能弱 |
🔗 相关笔记 #
最后更新: 2026-04-29