3. etcd 数据持久化:数据目录结构、WAL 日志与快照机制、数据一致性保证原理

etcd 作为分布式键值存储系统,其数据持久化机制是保障集群一致性与高可用的基石。在生产环境中,理解 etcd 的数据目录结构、预写日志(WAL)与快照(Snapshot)的协同工作原理,以及基于 Raft 协议的数据一致性保证,是设计备份与恢复策略的前提。本章将深入剖析这些核心机制。

3.1 数据目录结构

etcd 的数据目录通常通过 --data-dir 参数指定(默认 ${name}.etcd/)。该目录下包含多个关键子目录和文件,用于存储元数据、WAL 日志、快照以及临时数据。

目录/文件 说明 关键作用
member/ 存储当前成员节点的所有持久化数据 核心数据目录
member/snap/ 存放快照(snapshot)文件,格式为 0000000000000001-0000000000000001.snap 用于快速恢复数据状态
member/wal/ 存放预写日志(WAL)文件,格式为 0000000000000000-0000000000000000.wal 记录所有写操作,保证数据不丢失
member/wal/0.tmp WAL 文件写入时的临时文件 保证写入原子性
snap/ (旧版本)存放快照的备用目录 兼容性保留
备份要点: 备份 etcd 数据时,应同时备份 member/snap/ 和 member/wal/ 目录。仅备份快照可能导致最近少量操作丢失;仅备份 WAL 则恢复速度极慢。

3.2 WAL 日志与快照机制

etcd 采用 预写日志(Write-Ahead Logging, WAL) 与 快照(Snapshot) 相结合的策略,在保证数据持久性的同时控制存储空间与恢复时间。

3.2.1 WAL 日志:记录每一次写操作

  • 写入流程: 每次客户端发起写请求(Put、Delete、Txn),etcd 先将操作序列化为日志条目追加到 WAL 文件,待日志落盘后,再更新内存中的状态机(BoltDB 或 tree index)。
  • 文件管理: WAL 文件按序号递增命名,每个文件默认最大 64MB。当当前文件写满后,创建新文件继续写入。
  • 数据恢复: 节点重启时,从 WAL 中重放所有日志条目,重建完整状态机。

3.2.2 快照:压缩日志,加速恢复

  • 触发条件: 当 WAL 日志条目数达到 --snapshot-count(默认 100,000)时,etcd 自动创建快照。
  • 快照内容: 快照是某一时刻内存状态机的完整二进制副本,包含所有键值数据及其元数据。
  • 日志截断: 快照创建完成后,etcd 会删除该快照之前的所有 WAL 文件,仅保留快照之后的日志。
关键指标:
  • --snapshot-count:控制快照频率,值越小快照越频繁,恢复越快但磁盘 I/O 增加。
  • WAL 文件大小:默认 64MB,可通过 --wal-dir 指定独立磁盘以提升写入性能。
WAL 日志与快照协同工作流程 客户端写请求 WAL 日志写入 状态机更新 响应客户端 日志条目数达到 snapshot-count 创建快照(snap) 截断旧 WAL 文件 快照创建后,仅保留快照之后的 WAL 日志,大幅减少恢复时的日志重放量

3.3 数据一致性保证原理

etcd 基于 Raft 共识算法 实现强一致性。Raft 将节点分为 Leader、Follower 和 Candidate 三种角色,通过日志复制与多数派投票确保所有节点数据最终一致。

3.3.1 Raft 核心流程

  1. Leader 选举: 集群启动或 Leader 故障时,Follower 转换为 Candidate 并发起选举,获得多数票(n/2 + 1)的节点成为新 Leader。
  2. 日志复制: Leader 接收客户端写请求,将日志条目广播给所有 Follower。当多数 Follower 确认写入后,Leader 提交该条目并通知所有节点。
  3. 安全性保证: Raft 保证已提交的日志条目不会被覆盖,且只有包含最新已提交日志的节点才能成为 Leader。

3.3.2 线性一致性(Linearizability)

etcd 默认提供线性一致性读,即读操作返回的结果必须反映最近一次写操作完成后的状态。实现方式包括:

  • Leader 读: 所有读写请求都经过 Leader,Leader 在响应读请求前确认自己仍是当前任期 Leader(通过心跳)。
  • ReadIndex: Follower 处理读请求时,向 Leader 获取当前已提交的日志索引,等待本地状态机应用至该索引后再返回结果。
注意: 如果使用 Follower 读(通过 --experimental-enable-lease-checkpoint 或客户端指定),可能读到稍旧的数据,不满足线性一致性。生产环境建议默认使用 Leader 读。
Raft 日志复制与一致性保证 Leader 接收请求,广播日志 Follower 1 确认日志写入 Follower 2 确认日志写入 Follower 3 确认日志写入 多数派(≥2/3)确认后,Leader 提交日志,所有节点应用至状态机

3.4 数据持久化与备份策略建议

策略 方法 恢复时间 数据完整性
快照备份 etcdctl snapshot save 快(直接加载快照) 可能丢失快照后的少量操作
WAL 备份 实时复制 member/wal/ 目录 慢(需重放所有日志) 可恢复至任意时间点
快照 + WAL 定期快照 + 持续备份 WAL 中等(加载快照 + 重放增量日志) 接近零丢失(取决于 WAL 备份频率)
生产建议: 每 2 小时执行一次 etcdctl snapshot save,同时通过文件系统快照或 rsync 实时同步 WAL 目录。恢复时先加载最新快照,再重放快照之后的 WAL 日志,实现 RPO 小于 5 分钟。