2. etcd 存储架构基础:Raft日志、WAL文件、快照与数据库文件的关系

理解 etcd 的存储架构是进行压测调优的前提。etcd 的持久化层由四个核心组件构成:Raft 日志、WAL 文件、快照 (Snapshot) 和 数据库文件 (DB)。它们共同协作,保证了集群的强一致性与数据恢复能力。

2.1 核心组件定义与职责

组件 存储位置 核心职责 写入方式
Raft 日志 内存 + WAL 记录所有状态机变更操作(Put/Delete),用于节点间复制与共识 顺序追加
WAL 文件 磁盘 (wal 目录) Raft 日志的持久化载体,确保已提交日志不丢失 顺序追加 + fsync
快照 (Snapshot) 磁盘 (snap 目录) 压缩 Raft 日志,保存某一时刻的完整状态机数据 全量写入
数据库文件 (DB) 磁盘 (member/snap/db) 存储最终的键值数据,基于 BoltDB (etcd v3) 实现 B+树随机写入
关键认知: Raft 日志是“操作记录”,WAL 是日志的“磁盘保险箱”,快照是日志的“压缩包”,DB 文件是最终可查询的“数据仓库”。

2.2 数据写入与持久化流程

一次客户端写入请求在存储层的流转路径如下:

  1. 提案 (Propose): Leader 节点将写操作封装为 Raft 日志条目。
  2. 追加到 WAL: 日志条目先顺序写入当前 WAL 文件,并执行 fsync 确保落盘。
  3. 广播与提交: Leader 将日志条目复制给 Follower,多数节点确认后标记为“已提交”。
  4. 应用到状态机: 已提交的日志条目被应用到内存状态机,并写入 BoltDB 数据库文件。
  5. 返回客户端: 写入成功响应返回给客户端。
性能要点: 步骤 2 的 fsync 是写入延迟的主要瓶颈。步骤 4 的 BoltDB 写入涉及 B+树分裂与磁盘随机写,是吞吐量的关键限制因素。

2.3 快照与日志压缩机制

随着运行时间增长,Raft 日志会无限膨胀。etcd 通过快照机制进行日志压缩:

  • 触发条件: 当 Raft 日志条目数量达到 --snapshot-count 阈值(默认 100,000)时,触发快照。
  • 快照生成: etcd 将当前内存状态机数据序列化,写入 .snap 文件。
  • 日志截断: 快照生成后,该快照之前的所有 Raft 日志条目可以被安全删除。
  • 恢复流程: 新节点加入或节点崩溃恢复时,先加载最近的快照,再重放快照之后的少量 WAL 日志。
调优陷阱: 快照频率过高(--snapshot-count 过小)会导致频繁的全量磁盘 I/O,影响写入性能;频率过低则导致 WAL 日志文件过大,延长节点恢复时间。
etcd 存储架构核心组件关系图 客户端请求 Raft 共识模块 日志复制与提交 WAL 文件 顺序写入 + fsync 快照 (Snapshot) 日志压缩与全量状态 DB 文件 (BoltDB) B+树持久化存储 追加日志条目 触发压缩 应用状态 恢复时加载 数据流说明: 1. 写入请求 → Raft 共识 → WAL 持久化 → 状态应用 → DB 文件 2. 日志达到阈值 → 生成快照 → 截断 WAL → 释放磁盘空间

2.4 快照与 WAL 的协同恢复流程

当 etcd 节点重启或新节点加入时,恢复顺序至关重要:

  1. 加载快照: 从 snap 目录读取最新的 .snap 文件,将状态机恢复到快照时刻。
  2. 重放 WAL: 从快照对应的索引位置开始,顺序读取并重放 WAL 文件中的后续日志条目。
  3. 追赶进度: 如果 WAL 中仍有缺失,Leader 会通过 Raft 协议将缺失的日志条目发送给该节点。
恢复时间估算: 恢复时间 ≈ 快照加载时间 + (WAL 日志量 / 重放速率)。快照频率越高,WAL 日志量越少,恢复越快,但快照生成时的性能开销越大。
快照触发与日志压缩流程 Raft 日志条目序列 (按索引递增) 1 2 3 ... N N+1 ... M 生成快照 日志压缩后:索引 1~N 被截断,仅保留 N+1 之后的日志 N+1 ... M 快照保存索引 N 时刻的完整状态,索引 1~N 的日志可安全删除,释放磁盘空间。

2.5 性能调优关联点

理解上述关系后,压测调优的核心平衡点在于:

  • 快照频率 (--snapshot-count): 控制 WAL 日志保留量,直接影响磁盘空间占用和恢复速度。
  • WAL fsync 策略: 每次写入都 fsync 保证强一致性,但也是延迟的主要来源。
  • DB 文件 compaction: 历史版本数据的清理策略,影响 DB 文件大小和查询性能。
  • 磁盘 I/O 隔离: WAL 的顺序写与 DB 的随机写共享磁盘带宽,建议使用独立磁盘或高性能 SSD。