etcd 架构总览:整体架构图与各组件职责

etcd 是一个高可用的分布式键值存储系统,其内部架构采用分层设计,从上到下依次为网络层、共识层、存储层和持久化层。每一层各司其职,共同保证了 etcd 的强一致性、高可用性和数据可靠性。理解整体架构是深入掌握 etcd 数据流与故障处理的基础。

核心设计理念:etcd 将网络通信、分布式共识、状态机存储与日志持久化解耦,使得每一层都可以独立演进与优化。Raft 共识算法是 etcd 的“大脑”,而存储层与 WAL 则是其“记忆体”。

整体架构分层

etcd 的架构可以抽象为四个核心层次,每一层都封装了明确的职责,并通过清晰的接口进行交互。下表总结了各层的主要功能与关键组件:

层次 核心组件 主要职责
网络层 gRPC Server 处理客户端请求(KV、Watch、Lease、Cluster、Maintenance 等 gRPC 服务);负责连接管理与认证鉴权。
共识层 Raft 模块 实现 Raft 共识算法:Leader 选举、日志复制、安全性保证;将客户端请求转化为 Raft Log Entry。
存储层 MVCC、TreeIndex、Backend (boltdb) 维护多版本并发控制(MVCC)键值存储;管理 B+ 树索引与底层持久化存储。
持久化层 WAL、Snapshot WAL 记录所有 Raft Log 的追加写入,保证数据不丢失;Snapshot 压缩历史日志,加速重启恢复。
etcd 整体架构分层图 网络层 — gRPC Server KV · Watch · Lease · Cluster · Maintenance · Auth 接收客户端请求,解析协议,执行认证与限流 共识层 — Raft 模块 Leader 选举 · 日志复制 · 安全性 · 状态机 将客户端请求转为 Raft Log Entry,驱动集群达成一致 存储层 — MVCC · TreeIndex · Backend (boltdb) 多版本并发控制 · B+ 树索引 · 事务读写 维护键值数据的最新版本与历史版本,提供快照隔离 持久化层 — WAL · Snapshot 追加写日志 · 快照压缩 · 崩溃恢复

各组件职责详解

1. gRPC Server — 网络层

gRPC Server 是 etcd 对外的唯一入口,基于 HTTP/2 协议提供多路复用、流式传输和双向通信能力。它暴露了多个 gRPC 服务接口:

  • KV 服务:提供 Range、Put、DeleteRange、Txn 等原子操作。
  • Watch 服务:支持客户端监听键的变化,实现事件驱动。
  • Lease 服务:管理租约,用于键的自动过期与心跳保活。
  • Cluster 服务:成员管理、节点状态查询。
  • Maintenance 服务:状态检查、快照、碎片整理、报警。
  • Auth 服务:基于角色的访问控制(RBAC)。
性能要点:gRPC Server 使用连接池和请求复用,单连接可承载数千并发请求。etcd v3 版本完全基于 gRPC,不再支持 v2 API。

2. Raft 层 — 共识引擎

Raft 层是 etcd 分布式一致性的核心。它实现了 Raft 共识算法的全部关键机制:

  • Leader 选举:集群启动或 Leader 故障时,通过超时机制选举新 Leader。
  • 日志复制:Leader 将客户端请求封装为 Raft Log Entry,并行复制到所有 Follower。
  • 安全性:保证只有拥有最新日志的节点才能成为 Leader,防止已提交日志被覆盖。
  • 状态机:Raft 层将日志条目应用到内部状态机,驱动存储层变更。

Raft 层不直接操作磁盘,它将日志条目交给下层持久化组件处理,自身只维护内存中的日志索引与状态。

3. 存储层 — MVCC + TreeIndex + Backend

存储层负责管理 etcd 的所有键值数据,采用多版本并发控制(MVCC)模型:

  • TreeIndex:基于 B+ 树的内存索引,维护 key 到版本号(revision)的映射。支持高效的范围查询与前缀扫描。
  • Backend (boltdb):etcd 使用嵌入式 boltdb 作为底层持久化引擎。boltdb 是一个单机、支持事务的 B+ 树数据库,直接读写磁盘文件。
  • MVCC:每次写操作生成一个新的版本,旧版本数据保留在 boltdb 中,直到被压缩(Compaction)清理。读操作可以指定版本号,实现历史快照查询。
注意:boltdb 是单写者模型,所有写操作必须串行化。etcd 通过 Raft 层将并发写请求序列化为日志条目,再交由 boltdb 单线程执行,从而保证全局一致性。

4. WAL 与 Snapshot — 持久化层

持久化层是 etcd 数据不丢失的最后一道防线,由 WAL(Write-Ahead Log)和 Snapshot 两部分组成:

组件 写入方式 核心作用 文件格式
WAL 追加写(Append-only) 记录所有 Raft Log Entry,崩溃后重放恢复内存状态 二进制分段文件(wal-xxx)
Snapshot 全量快照 压缩历史日志,加速重启;用于 Follower 追赶 Leader 二进制快照文件(snap-xxx)

WAL 在每次 Raft 日志提交前强制刷盘(fsync),保证日志持久化。Snapshot 定期将当前状态机数据写入磁盘,并删除该时间点之前的 WAL 文件,避免日志无限增长。

etcd 内部数据流与组件协作图 客户端 (gRPC 请求) gRPC Server Raft 模块 WAL (追加写) 存储层 (boltdb) Snapshot (快照) 定期触发快照 数据流方向:客户端 → gRPC Server → Raft 模块 → 并行写入 WAL 与存储层

组件协作流程简述

  1. 客户端请求到达:gRPC Server 接收 Put、Range 等请求,进行认证与参数校验。
  2. 请求转为 Raft 日志:Raft 模块将请求封装为 Log Entry,Leader 节点将日志并行复制到多数派 Follower。
  3. 日志持久化:WAL 组件将 Log Entry 追加写入磁盘文件,并执行 fsync 确保落盘。
  4. 日志应用到状态机:当日志被多数派确认后,Raft 模块将日志应用到存储层(boltdb),更新内存索引与磁盘数据。
  5. 响应客户端:存储层写入成功后,gRPC Server 将结果返回给客户端。
  6. 快照压缩:当 WAL 文件达到阈值时,etcd 生成当前状态机的 Snapshot,并清理过期日志。
关键理解:etcd 的写路径是“先日志后状态机”——所有写操作必须先写入 WAL 并达成共识,才能应用到存储层。这种设计保证了即使节点崩溃,重启后也能通过 WAL 重放恢复完整状态。