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指定独立磁盘以提升写入性能。
3.3 数据一致性保证原理
etcd 基于 Raft 共识算法 实现强一致性。Raft 将节点分为 Leader、Follower 和 Candidate 三种角色,通过日志复制与多数派投票确保所有节点数据最终一致。
3.3.1 Raft 核心流程
- Leader 选举: 集群启动或 Leader 故障时,Follower 转换为 Candidate 并发起选举,获得多数票(
n/2 + 1)的节点成为新 Leader。 - 日志复制: Leader 接收客户端写请求,将日志条目广播给所有 Follower。当多数 Follower 确认写入后,Leader 提交该条目并通知所有节点。
- 安全性保证: Raft 保证已提交的日志条目不会被覆盖,且只有包含最新已提交日志的节点才能成为 Leader。
3.3.2 线性一致性(Linearizability)
etcd 默认提供线性一致性读,即读操作返回的结果必须反映最近一次写操作完成后的状态。实现方式包括:
- Leader 读: 所有读写请求都经过 Leader,Leader 在响应读请求前确认自己仍是当前任期 Leader(通过心跳)。
- ReadIndex: Follower 处理读请求时,向 Leader 获取当前已提交的日志索引,等待本地状态机应用至该索引后再返回结果。
注意: 如果使用 Follower 读(通过
--experimental-enable-lease-checkpoint 或客户端指定),可能读到稍旧的数据,不满足线性一致性。生产环境建议默认使用 Leader 读。
3.4 数据持久化与备份策略建议
| 策略 | 方法 | 恢复时间 | 数据完整性 |
|---|---|---|---|
| 快照备份 | etcdctl snapshot save |
快(直接加载快照) | 可能丢失快照后的少量操作 |
| WAL 备份 | 实时复制 member/wal/ 目录 |
慢(需重放所有日志) | 可恢复至任意时间点 |
| 快照 + WAL | 定期快照 + 持续备份 WAL | 中等(加载快照 + 重放增量日志) | 接近零丢失(取决于 WAL 备份频率) |
生产建议: 每 2 小时执行一次
etcdctl snapshot save,同时通过文件系统快照或 rsync 实时同步 WAL 目录。恢复时先加载最新快照,再重放快照之后的 WAL 日志,实现 RPO 小于 5 分钟。