2. etcd 数据模型与存储:key-value 存储模型、MVCC 机制、数据目录结构、WAL 与 snapshot
etcd 作为分布式键值存储系统,其底层数据模型与存储引擎的设计直接决定了集群的可靠性、读写性能以及灾难恢复能力。理解 etcd 如何组织数据、管理多版本并发控制、维护预写日志与快照,是制定备份策略和优化 RPO 的基础。
2.1 Key-Value 存储模型
etcd 采用扁平的 key-value 模型,所有数据以二进制字节数组形式存储。Key 按字典序排序,支持前缀扫描与范围查询。与关系型数据库不同,etcd 不提供表、行、列的概念,而是将数据组织为有序的键值映射。
| 特性 | 说明 |
|---|---|
| Key 类型 | 字节数组([]byte),最大 1 MB |
| Value 类型 | 字节数组([]byte),最大 1 MB |
| 排序规则 | 按 Key 的字节序(byte-wise)升序排列 |
| 版本管理 | 每个 Key 维护多个版本,通过 revision 标识 |
| 租约关联 | Key 可绑定租约(Lease),租约过期自动删除 Key |
运维提示: 备份时需注意 Key 的租约状态。如果备份后恢复,租约时间可能已过期,导致 Key 被自动清理。建议在恢复后检查租约有效期,必要时重新创建租约。
2.2 MVCC 机制与 Revision
etcd 使用多版本并发控制(MVCC)来支持历史版本查询与事务隔离。每个修改操作(Put、Delete)都会生成一个全局递增的 revision(主版本号),用于标识数据变更的顺序。
- 全局 revision: 集群内单调递增,每次事务提交时递增 1。
- Key 的版本(version): 单个 Key 的修改次数,从 1 开始递增。
- 历史版本保留: 默认保留所有历史版本,可通过
--auto-compaction-retention设置自动压缩策略。
MVCC 核心流程:
- 客户端发起 Put(key, value) 请求。
- etcd 分配新的全局 revision(如 1001)。
- 将 (revision, key, value) 写入底层存储(boltdb)。
- 更新 Key 的当前版本号(version +1)。
- 旧版本数据仍保留,直到被压缩(compaction)清理。
2.3 数据目录结构
etcd 的数据目录通常位于 --data-dir 指定的路径下(默认 ${name}.etcd/)。理解目录结构有助于定位备份文件与诊断问题。
${data-dir}/
├── member/
│ ├── snap/ # 快照文件目录
│ │ └── 0000000000000001-0000000000000001.snap
│ ├── wal/ # 预写日志目录
│ │ ├── 0000000000000000-0000000000000000.wal
│ │ └── 0.tmp # 临时 WAL 文件(写入中)
│ └── backend/ # boltdb 数据库文件
│ └── db # 主存储文件(包含所有 key-value 数据)
├── wal/ # 软链接到 member/wal(旧版本兼容)
└── snap/ # 软链接到 member/snap(旧版本兼容)
| 文件/目录 | 作用 | 备份关注点 |
|---|---|---|
member/snap/ |
存储 etcd 快照文件(.snap),用于快速恢复 | 定期备份快照文件,作为 RPO 优化基础 |
member/wal/ |
存储预写日志(.wal),记录所有写操作 | WAL 文件用于增量恢复,需保留足够历史 |
member/backend/db |
boltdb 数据库文件,存储所有当前和历史数据 | 备份时需确保文件一致性(建议使用 etcdctl snapshot save) |
重要: 直接复制
member/backend/db 文件进行备份是不安全的,因为 boltdb 在运行时可能处于不一致状态。必须使用 etcdctl snapshot save 或 etcd 内置的 snapshot API 创建一致性快照。
2.4 WAL(预写日志)
WAL(Write-Ahead Log)是 etcd 保证数据持久性的核心机制。所有写操作在应用到 boltdb 之前,必须先写入 WAL 文件。WAL 文件按段(segment)组织,每个段文件大小默认为 64 MB。
- 写入顺序: 先写 WAL,再写 boltdb。如果 etcd 崩溃,重启时通过回放 WAL 恢复未持久化的数据。
- 文件命名:
{起始索引}-{长度}.wal,例如0000000000000000-0000000000000000.wal。 - WAL 记录类型: 包括普通写入记录、元数据记录、快照记录等。
- WAL 压缩: 创建快照后,之前的 WAL 文件可以被安全删除(由 etcd 自动管理)。
WAL 在备份恢复中的角色:
- 快照文件提供某一时刻的全量数据。
- WAL 文件提供快照之后的所有增量变更。
- 恢复时:先加载快照,再回放快照之后的 WAL 记录,达到最新一致状态。
- RPO 优化目标:通过高频快照 + 保留足够 WAL,将数据丢失窗口控制在秒级。
2.5 Snapshot(快照)
快照是 etcd 在某个时间点的全量数据副本,用于加速恢复和压缩 WAL。etcd 支持两种快照机制:
| 快照类型 | 触发方式 | 文件格式 | 用途 |
|---|---|---|---|
| 自动快照 | WAL 文件数量达到阈值(默认 10000 条记录) | .snap 文件 |
内部压缩 WAL,加速重启恢复 |
| 手动快照 | etcdctl snapshot save 命令 |
.db 文件(实际是 boltdb 副本) |
备份、迁移、灾难恢复 |
2.6 数据压缩与历史版本清理
随着时间推移,MVCC 历史版本会占用大量磁盘空间。etcd 通过压缩(compaction)机制清理旧版本数据。
- 自动压缩: 通过
--auto-compaction-retention设置保留时间(如 1h),etcd 定期删除超过保留期的历史版本。 - 手动压缩: 使用
etcdctl compaction <revision>手动触发压缩。 - 碎片整理: 压缩后 boltdb 文件不会立即缩小,需执行
etcdctl defrag回收磁盘空间。
备份策略影响: 如果压缩间隔过短,历史版本被快速清理,可能导致基于 WAL 的增量恢复失败(因为需要的 WAL 记录已被删除)。建议在备份策略中协调压缩参数与 WAL 保留策略,确保快照 + WAL 能够完整恢复到目标时间点。