2. etcd 架构速览:Raft 共识算法、WAL 日志、MVCC、boltdb 存储引擎、gRPC API 接口

在深入压测与瓶颈定位之前,必须建立对 etcd 核心架构的清晰认知。etcd 是一个高度一致的分布式键值存储系统,其架构可抽象为五个关键层次:共识层(Raft)、持久化层(WAL)、并发控制层(MVCC)、存储引擎层(boltdb)以及通信层(gRPC)。每一层都是潜在的性能瓶颈点,也是 Prometheus 指标监控的核心对象。

架构视角提示: 压测时观察到的延迟抖动、吞吐量上限、资源消耗异常,几乎都能追溯到这五层中的某一层。理解它们之间的数据流与依赖关系,是精准定位瓶颈的前提。

2.1 整体架构与数据流

下图展示了 etcd 的核心组件及其交互流程。一个写入请求从客户端发出到最终持久化,需要依次经过 gRPC 接口、Raft 共识模块、WAL 日志、MVCC 层,最后写入 boltdb 存储引擎。

etcd 核心架构与数据流 客户端 (Client) gRPC API 接口 Raft 共识模块 (Leader 选举 / 日志复制) WAL 日志 (顺序写入 / 崩溃恢复) MVCC 并发控制 (多版本 / 事务隔离) boltdb 存储引擎 (B+树 / 内存映射文件) 磁盘 (Disk) 数据流说明: 1. 客户端通过 gRPC 发起 Put/Delete/Txn 请求。 2. 请求经 Raft 模块达成共识后,先写入 WAL 日志,再提交到 MVCC 层,最终由 boltdb 持久化到磁盘。

2.2 Raft 共识算法

Raft 是 etcd 实现强一致性的核心。它将分布式共识问题分解为三个子问题:Leader 选举、日志复制和安全性。etcd 集群通常由 3 或 5 个节点组成,每个节点处于 Leader、Follower 或 Candidate 三种状态之一。

  • Leader 选举: 当 Follower 在选举超时内未收到 Leader 心跳,则转为 Candidate 并发起选举。获得多数票的节点成为新 Leader。
  • 日志复制: 所有写请求必须由 Leader 处理。Leader 将日志条目(Entry)并行复制到所有 Follower,并在收到多数确认后提交。
  • 安全性: Raft 保证已提交的日志条目不会被覆盖,且只有日志最新的节点才能当选 Leader。
Raft 角色与职责
角色 职责 压测关注点
Leader 处理所有客户端写请求;管理日志复制;发送心跳 CPU 负载、网络带宽、RTT 延迟
Follower 响应 Leader 的日志复制请求;转发读请求(如需线性一致性) 磁盘 I/O(WAL 写入)、网络接收
Candidate 选举超时后发起投票;仅在选举期间存在 选举延迟、集群可用性
瓶颈提示: 在压测中,如果观察到 etcd_server_leader_changes_seen_total 指标频繁增长,说明集群 Leader 不稳定,通常由网络分区或磁盘 I/O 抖动引起。此时写吞吐量会急剧下降。

2.3 WAL 日志(Write-Ahead Logging)

WAL 是 etcd 持久化的第一道防线。所有 Raft 日志条目在应用到状态机之前,必须先顺序写入 WAL 文件。WAL 的设计目标是崩溃恢复:即使节点宕机,重启后也能通过回放 WAL 重建内存状态。

  • 顺序写入: WAL 采用追加写模式,避免随机 I/O,最大化磁盘吞吐量。
  • 文件分段: 单个 WAL 文件达到阈值(默认 64MB)后,会创建新文件。旧文件在数据被快照覆盖后可被清理。
  • 同步策略: 通过 --wal-sync 参数控制每次写入是否调用 fsync。同步写入保证数据安全,但会显著增加延迟。
# WAL 相关关键 Prometheus 指标
etcd_disk_wal_fsync_duration_seconds_count   # fsync 调用次数
etcd_disk_wal_fsync_duration_seconds_sum     # fsync 总耗时
etcd_server_proposals_failed_total           # 提案失败次数(可能由 WAL 写入慢导致)
压测陷阱: 如果 WAL 所在磁盘是共享的或使用网络存储(如 NFS),fsync 延迟可能飙升到 100ms 以上,直接导致 Raft 心跳超时和 Leader 切换。务必使用本地 NVMe SSD 并监控 etcd_disk_wal_fsync_duration_seconds 的 P99 值。

2.4 MVCC 并发控制

etcd 使用多版本并发控制(MVCC)来支持并发读写而不加锁。每个键的每次修改都会生成一个新的版本号(revision),旧版本数据保留一段时间供历史查询或 Watch 使用。

  • 版本管理: 全局单调递增的 revision 主版本号,以及每个键的 mod_revision 和 create_revision。
  • 事务隔离: 基于 revision 的快照读,保证读写不冲突。写事务通过乐观锁(比较-交换模式)检测冲突。
  • 历史版本压缩: 通过 --auto-compaction-retention 定期压缩旧版本,防止存储空间无限增长。
MVCC 核心概念
概念 说明 压测影响
revision 全局版本号,每次写操作递增 高并发写入时 revision 增长快,影响 boltdb 索引大小
历史版本 旧版本数据保留在 boltdb 中 未及时压缩会导致存储膨胀和读放大
Watch 基于 revision 的事件流 大量 Watch 客户端会增加 MVCC 层的事件分发开销

2.5 boltdb 存储引擎

boltdb 是 etcd 的底层持久化存储引擎,基于 B+ 树实现,支持事务和内存映射文件(mmap)。etcd 将 MVCC 的键值对序列化后写入 boltdb 的 bucket 中。

  • B+ 树结构: 所有数据按 key 排序存储在 B+ 树中,支持高效的范围查询和顺序遍历。
  • 事务模型: 支持读写事务,但同一时刻只允许一个读写事务(写串行化),读事务可以并发。
  • 内存映射: boltdb 将数据库文件映射到进程地址空间,读写操作直接操作内存,由操作系统负责刷盘。
# boltdb 相关关键 Prometheus 指标
etcd_mvcc_db_total_size_in_bytes             # boltdb 文件大小
etcd_mvcc_db_open_read_transactions          # 当前打开的读事务数
etcd_server_backend_commit_duration_seconds  # boltdb 事务提交耗时
瓶颈提示: 当 etcd_server_backend_commit_duration_seconds 的 P99 超过 1 秒时,说明 boltdb 事务提交成为瓶颈。常见原因包括:磁盘 I/O 饱和、B+ 树分裂频繁、或历史版本过多导致索引膨胀。

2.6 gRPC API 接口

etcd 对外暴露 gRPC API,支持 KV 服务(Put/Get/Delete/Txn)、Watch 服务、Lease 服务和 Cluster/Maintenance 服务。gRPC 基于 HTTP/2 协议,支持双向流、多路复用和头部压缩。

  • 请求模型: 客户端通过 Protobuf 序列化请求,gRPC 将请求路由到对应的 etcd 服务处理函数。
  • 流式 Watch: Watch 客户端通过 gRPC 流持续接收事件,避免了轮询开销。
  • 拦截器: etcd 内置了 Prometheus 指标拦截器,自动记录每个 gRPC 方法的调用次数、延迟和错误码。
核心 gRPC 服务与压测指标
服务 主要 RPC 关键 Prometheus 指标
KV Put / Get / Delete / Txn etcd_grpc_requests_total、etcd_grpc_server_handling_seconds
Watch Create / Watch etcd_grpc_requests_total{method="Watch"}、etcd_server_watch_events_total
Lease Grant / Revoke / KeepAlive etcd_server_lease_expired_total
Cluster MemberAdd / MemberRemove / MemberList etcd_server_health_failures
压测建议: 使用 grpcurl 或 etcd 自带的 benchmark 工具直接发送 gRPC 请求,可以绕过 etcdctl 的序列化开销,更准确地测量 etcd 服务端性能。监控 etcd_grpc_server_handling_seconds 的延迟分布,是定位 gRPC 层瓶颈的直接手段。

2.7 架构层次总结

下表汇总了各层的核心职责、性能敏感点以及对应的 Prometheus 监控指标,方便在压测时快速对照排查。

架构层 核心职责 性能敏感点 关键 Prometheus 指标
gRPC API 协议解析、请求路由、流管理 连接数、请求大小、序列化开销 etcd_grpc_server_handling_seconds
Raft 共识达成、日志复制、Leader 选举 网络延迟、心跳间隔、选举超时 etcd_server_leader_changes_seen_total
WAL 顺序日志写入、崩溃恢复 磁盘 fsync 延迟、写入带宽 etcd_disk_wal_fsync_duration_seconds
MVCC 多版本管理、事务隔离、Watch 事件 版本数、压缩频率、Watch 客户端数 etcd_mvcc_put_total
boltdb B+ 树存储、事务提交、内存映射 磁盘 I/O、B+ 树分裂、事务冲突 etcd_server_backend_commit_duration_seconds