2. etcd 架构与数据持久化机制
etcd 是一个强一致性的分布式键值存储系统,其核心架构围绕 Raft 共识协议 构建。理解 etcd 的架构与数据持久化机制,是进行 snapshot 治理、配置蓝绿发布以及漂移审计的基础。本章将深入剖析 Raft 协议基础、WAL 日志、snapshot 触发条件以及数据文件结构。
2.1 Raft 协议基础
Raft 是一种易于理解的分布式共识算法,etcd 使用它来保证集群中数据的一致性和高可用性。Raft 将集群中的节点分为三种角色:Leader、Follower 和 Candidate。
- Leader:负责处理所有客户端请求,并将日志条目复制到 Follower 节点。正常情况下,集群只有一个 Leader。
- Follower:被动接收来自 Leader 的日志复制,并响应投票请求。如果 Follower 在一段时间内未收到 Leader 的心跳,会转变为 Candidate。
- Candidate:用于选举新的 Leader。Candidate 会向其他节点发起投票请求,获得多数票后成为 Leader。
Raft 协议的核心流程包括 Leader 选举 和 日志复制。日志复制保证了所有节点最终执行相同的操作序列,从而达成一致状态。
2.2 WAL 日志
WAL(Write-Ahead Log,预写式日志) 是 etcd 数据持久化的基石。在 etcd 中,任何数据修改操作(如 put、delete)都不会直接修改磁盘上的数据文件,而是先以日志条目的形式顺序追加到 WAL 文件中。
WAL 文件存储在 etcd 数据目录的 member/wal/ 子目录下。每个 WAL 文件由多个 日志条目(Log Entry) 组成,每个条目包含以下关键字段:
| 字段 | 说明 | 作用 |
|---|---|---|
| Term | Leader 任期号 | 用于检测网络分区和过期的 Leader |
| Index | 日志条目在日志序列中的唯一索引 | 用于日志匹配和一致性检查 |
| Type | 操作类型(如 put、delete) |
决定如何应用该日志到状态机 |
| Data | 序列化的键值对数据 | 实际要存储或删除的数据内容 |
WAL 日志的写入是 顺序 I/O,性能极高。etcd 默认每提交一批日志条目后,就会调用 fsync 将数据强制刷入磁盘,以确保持久性。
2.3 Snapshot 触发条件
随着时间推移,WAL 日志会不断增长,占用大量磁盘空间,并且重启时重放所有日志会变得非常缓慢。为了解决这个问题,etcd 引入了 Snapshot(快照) 机制。Snapshot 记录了某个时间点 etcd 键值存储的完整状态,生成 Snapshot 后,该时间点之前的所有 WAL 日志都可以被安全地清理。
Snapshot 的触发条件主要有以下几种:
- WAL 文件数量阈值(默认 10000 个文件):当 WAL 文件数量超过
--snapshot-count参数配置的值时,etcd 会自动触发 Snapshot。 - 手动触发:通过
etcdctl snapshot save命令手动创建 Snapshot 文件。 - 空间配额触发:当 etcd 后端数据库(boltdb)大小接近配额(默认 2GB)时,etcd 会触发 Snapshot 并压缩历史数据。
--snapshot-count 参数。
2.4 数据文件结构
etcd 的数据目录结构清晰,主要包含以下关键文件和子目录:
| 路径/文件 | 说明 | 用途 |
|---|---|---|
member/snap/ |
Snapshot 文件存储目录 | 存储生成的 .snap 文件,用于快速恢复和日志压缩 |
member/wal/ |
WAL 日志文件存储目录 | 存储 .wal 文件,记录所有写操作日志 |
member/snap/db |
后端 boltdb 数据库文件 | 存储 etcd 的键值数据,是 Snapshot 的核心内容 |
member/wal/0.tmp |
临时 WAL 文件 | 在 WAL 文件切换或写入过程中临时存在 |
etcd 使用 boltdb 作为其底层存储引擎。boltdb 是一个嵌入式、事务性的键值数据库,它将数据存储在一个单一的 db 文件中。Snapshot 文件本质上是对 db 文件在某个时间点的物理拷贝,并附加了元数据信息(如快照时的 Raft 状态)。
理解这些文件结构,对于后续进行 Snapshot 治理、配置蓝绿发布以及漂移审计至关重要。例如,在蓝绿部署中,可以通过对比不同集群的 Snapshot 文件来检测配置漂移。