2. etcd 基础架构回顾:Raft 共识算法原理、集群角色与存储引擎
在深入灾备与压测之前,必须重新审视 etcd 的底层架构。etcd 本质上是一个强一致性的分布式键值存储系统,其核心由三层构成:共识层(Raft)、集群角色层和存储引擎层(BoltDB)。理解这三层的协作关系,是制定灾备策略和解读压测指标的前提。
2.1 Raft 共识算法原理
Raft 是一种易于理解的分布式共识算法,它通过领导者选举和日志复制两个核心机制,确保集群中所有节点数据最终一致。etcd 使用 Raft 来保证即使部分节点故障,集群仍能对外提供一致的服务。
核心要点: Raft 将共识问题分解为三个子问题:领导者选举(Leader Election)、日志复制(Log Replication)和安全性(Safety)。
2.1.1 领导者选举与任期
Raft 集群中的每个节点都处于三种状态之一:Follower、Candidate 或 Leader。选举过程通过任期(Term)来划分时间片,每个任期最多只有一个 Leader。
- 选举触发: Follower 在选举超时时间内未收到 Leader 的心跳,则转换为 Candidate 并发起选举。
- 投票机制: Candidate 获得超过半数(N/2+1)节点的投票,即可成为 Leader。
- 心跳维持: Leader 定期向所有 Follower 发送心跳(AppendEntries RPC),重置选举超时计时器。
2.1.2 日志复制与提交
所有写操作必须经过 Leader。Leader 将客户端请求封装为日志条目(Log Entry),并复制到大多数 Follower 节点后,才将日志标记为已提交(Committed)并应用到状态机。
- 客户端向 Leader 发送写请求。
- Leader 将请求追加到本地日志,并并行向 Follower 发送 AppendEntries RPC。
- 当 Leader 收到大多数节点的成功响应后,日志条目进入已提交状态。
- Leader 将结果返回给客户端,并通知 Follower 应用该日志到状态机。
灾备启示: 日志复制需要多数派确认。如果集群因故障丢失多数节点(如 3 节点集群只剩 1 个节点),将无法提交新日志,集群进入只读或不可用状态。这是灾备设计的关键阈值。
2.2 etcd 集群角色:Leader / Follower
etcd 集群通常由奇数个节点组成(如 3、5、7),每个节点在 Raft 协议下扮演特定角色。角色并非固定不变,故障时会动态转换。
| 角色 | 职责 | 状态特征 | 灾备关注点 |
|---|---|---|---|
| Leader | 处理所有客户端写请求;管理日志复制;发送心跳 | 唯一;定期发送心跳;拥有最新日志 | Leader 故障触发重新选举,期间不可写 |
| Follower | 处理读请求(可配置);转发写请求给 Leader;参与投票 | 被动;接收心跳;同步 Leader 日志 | Follower 故障不影响写入,但降低读可用性 |
| Candidate | 选举过渡角色;发起投票请求 | 短暂存在;选举超时后触发 | 选举风暴可能导致集群短暂不可用 |
压测陷阱: 在高并发写入压测时,如果 Leader 节点负载过高导致心跳超时,可能触发不必要的重新选举。压测前应监控 Leader 的 CPU 和网络延迟,确保选举超时参数(--election-timeout)配置合理。
2.3 数据模型与存储引擎:BoltDB
etcd 的数据最终持久化在底层的 BoltDB 中。BoltDB 是一个基于 B+ 树的嵌入式键值存储引擎,支持事务和 ACID 特性。理解 BoltDB 的结构有助于分析 etcd 的读写性能瓶颈和磁盘空间占用。
2.3.1 数据模型层次
etcd 的数据模型分为三层:
- Key-Value 层: 用户可见的逻辑键值对,支持前缀查询和目录结构。
- MVCC 层: 多版本并发控制,每个修改生成一个新的版本号(revision),支持历史版本查询和 Watch 机制。
- BoltDB 层: 物理存储层,将 MVCC 数据以 B+ 树结构持久化到磁盘文件(通常是 member/snap/db)。
2.3.2 BoltDB 存储结构
BoltDB 内部使用 Bucket 来组织数据。etcd 主要使用两个核心 Bucket:
| Bucket 名称 | 存储内容 | Key 格式 | Value 格式 |
|---|---|---|---|
| key | 用户键值对的主数据 | revision(主键 + 子ID) | 用户 Value + 元数据 |
| meta | 集群元数据(如当前 revision、集群 ID) | 固定名称 | 序列化结构体 |
性能启示: BoltDB 的 B+ 树特性决定了顺序写入性能远优于随机写入。etcd 的 MVCC 机制天然将写入转化为顺序追加(新 revision 递增),这是 etcd 写入性能较高的底层原因。压测时应避免大量跨 revision 范围的随机读取,这会导致 B+ 树频繁分裂。
2.4 架构总结:三者的协作关系
etcd 的一次完整写入流程,串联了上述三个核心组件:
- 客户端 → Leader: 写请求通过 gRPC 发送到集群 Leader。
- Raft 层: Leader 将请求封装为日志条目,通过 Raft 协议复制到多数 Follower。
- 状态机应用: 日志提交后,Leader 将数据应用到 MVCC 状态机,生成新的 revision。
- BoltDB 持久化: MVCC 将数据以 revision 为 Key 写入 BoltDB 的 "key" Bucket,并更新 "meta" Bucket。
- 返回客户端: Leader 向客户端返回写入成功响应。