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 协议要求集群中超过半数(N/2 + 1)的节点可用,才能对外提供服务。例如,一个 3 节点集群允许 1 个节点故障;一个 5 节点集群允许 2 个节点故障。

Raft 协议的核心流程包括 Leader 选举 和 日志复制。日志复制保证了所有节点最终执行相同的操作序列,从而达成一致状态。

Raft 协议角色与日志复制流程 Raft 协议角色与日志复制流程 Leader 处理请求,复制日志 Follower 被动接收日志 Candidate 发起选举投票 日志复制 选举超时 日志复制流程 1. 客户端请求发送给 Leader。 2. Leader 将请求追加到本地日志,并并行发送 AppendEntries RPC 给所有 Follower。 3. 当多数节点(Quorum)成功写入日志后,Leader 提交该日志条目并应用到状态机。 4. Leader 通知 Follower 提交,最终所有节点状态一致。

2.2 WAL 日志

WAL(Write-Ahead Log,预写式日志) 是 etcd 数据持久化的基石。在 etcd 中,任何数据修改操作(如 put、delete)都不会直接修改磁盘上的数据文件,而是先以日志条目的形式顺序追加到 WAL 文件中。

核心原则: 日志先于数据写入。这意味着即使系统在写入数据文件之前崩溃,重启后也可以通过重放 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 的触发条件主要有以下几种:

  1. WAL 文件数量阈值(默认 10000 个文件):当 WAL 文件数量超过 --snapshot-count 参数配置的值时,etcd 会自动触发 Snapshot。
  2. 手动触发:通过 etcdctl snapshot save 命令手动创建 Snapshot 文件。
  3. 空间配额触发:当 etcd 后端数据库(boltdb)大小接近配额(默认 2GB)时,etcd 会触发 Snapshot 并压缩历史数据。
注意: 频繁的 Snapshot 操作会消耗大量 I/O 和 CPU 资源,可能导致 etcd 服务性能抖动。在生产环境中,需要根据业务负载合理调整 --snapshot-count 参数。
Snapshot 触发与 WAL 清理流程 Snapshot 触发与 WAL 清理流程 WAL 日志序列(持续增长) ...... 触发条件 生成 Snapshot 记录当前完整状态 清理后 WAL Snapshot 作用 • 压缩 WAL 日志,释放磁盘空间。 • 加速节点重启恢复速度(只需加载 Snapshot + 少量增量日志)。

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 状态)。

数据流总结: 客户端请求 → Leader 写入 WAL 日志 → 日志提交 → 应用到 boltdb 状态机 → 定期生成 Snapshot 并清理旧 WAL。

理解这些文件结构,对于后续进行 Snapshot 治理、配置蓝绿发布以及漂移审计至关重要。例如,在蓝绿部署中,可以通过对比不同集群的 Snapshot 文件来检测配置漂移。