etcd

分布式系统的”真相之源”:Raft 强一致 + 键值 API + watch,Kubernetes 的全部状态都躺在它肚子里


项目速览

项目 内容
仓库 etcd-io/etcd
语言 Go
协议 Apache-2.0
一致性 Raft(线性一致读写)
接口 gRPC(etcdctl 命令行封装)
生产部署 3 或 5 节点集群 + TLS + 定期快照

它想解决什么问题

很多大名鼎鼎的系统背后,都藏着一个低调却关键的组件。Kubernetes 的每一个 Pod、Service、Secret 的期望状态,最终都写在 etcd 里;调度器的每一次选主、每个节点的租约续期,也要经过它。

它解决的问题很朴素但极难做对:让多个节点对同一份小数据达成强一致,并且在部分节点挂掉时仍然可用。自己实现 Raft、处理网络分区、脑裂、快照与恢复,是那种”写起来三个月、调起来三年”的活。etcd 把这件难事封装成了几个键值 API。

核心机制拆解

1. Raft 带来的强一致与高可用。 基于 Raft 实现线性一致的读写,三五个节点即可组成容错集群。写请求要多数派确认才返回,所以”读到的一定是最新已提交值”——这是所有上层协调逻辑的地基。

2. 极简的数据模型。 键值对存储,键按字典序排列,因此支持前缀区间查询(get /registry/pods --prefix)与监听(watch)变更。K8s 的 list-watch 机制就是建在这两件事上的:一次全量 list,然后靠 watch 增量跟进。

3. 租约与选举。 提供 lease(租约)机制与分布式锁原语。租约绑定 TTL,续不上就自动删除——服务注册、节点心跳、选主这三类需求都靠它表达,不需要额外的协调服务。

4. gRPC 与快照。 对外暴露 gRPC API,支持快照与增量备份。运维上这条很重要:etcd 的恢复只能从快照走,没有快照就等于没有备份。

5. 被大规模验证。 作为 Kubernetes 的默认后端,它承载着全球无数生产集群的元数据。这个验证规模在分布式存储里几乎没有对手。

安装与上手

1
2
3
4
5
6
7
8
# 单节点(仅用于体验,不要上生产)
docker run --rm -p 2379:2379 -p 2380:2380 \
quay.io/coreos/etcd:v3.5.0 \
/usr/local/bin/etcd

# 基础读写
ETCDCTL_API=3 etcdctl put foo bar
ETCDCTL_API=3 etcdctl get foo

生产环境通常是 3 或 5 节点的静态/动态集群,并开启 TLS 与定期快照。集群规模别贪多——Raft 的写入延迟随节点数上升,5 节点已经是常见上限。

点评

亮点是”把难事封装成简单 API”的完成度:你不必自己造 Raft,直接站在 etcd 的肩膀上即可。list-watch + 前缀查询这套组合拳,在很长一段时间里是构建控制器与配置中心最顺手的原语,K8s 生态里的无数 Operator 都复用了同一套模式。

局限要认清:它容量有限,是为”小数据、强一致”设计的——别拿它存大对象或做通用 KV 缓存,官方建议的库大小是 GB 量级;写入吞吐远低于最终一致的系统,适合元数据而不适合业务数据;运维门槛不低,磁盘 fsync 延迟直接决定集群稳定性,慢盘会拖死整个集群;一次误删或损坏若无快照几乎无法恢复;此外近年 K8s 社区在探索更省资源的替代方案,长期选型时值得关注演进方向。

适合人群:Kubernetes 与编排系统的维护者;需要服务发现、配置中心、分布式锁的基础设施团队;以及任何有”多节点强一致小数据”协调需求的系统架构师。

etcd 的价值不在它做了什么炫技的事,而在于它让”分布式一致性”这件原本只属于少数人的能力,变成了一个 put 与 get。