2. etcd 基础回顾:Raft 协议、键值存储模型、Watch 机制、Lease 机制

在深入压测与限流调优之前,必须重新夯实 etcd 的四大核心基础。这些机制直接决定了 etcd 在集群压力下的行为边界:Raft 保障一致性但引入延迟,键值存储模型影响读写放大,Watch 机制是长连接压力的主要来源,Lease 机制则与存储回收和心跳风暴密切相关。

2.1 Raft 协议:共识与日志复制

etcd 使用 Raft 协议在集群节点间达成强一致性。Raft 将节点角色分为 Leader、Follower 和 Candidate,通过 Leader 选举和日志复制两个核心流程保证所有节点数据最终一致。

关键压测影响点: 每次写入必须经过 Leader,并等待多数节点(Quorum)确认后才返回成功。集群节点数越多,网络往返次数越多,写入延迟随 Quorum 大小线性增长。3 节点集群容忍 1 节点故障,5 节点集群容忍 2 节点故障,但写入延迟更高。
Raft 日志复制流程(一次成功写入) Client Leader Follower 1 Follower 2 ① Propose ② AppendEntries ② AppendEntries ③ 多数确认(Quorum) ④ 提交 + 响应 Raft 关键参数与压测关联 • Heartbeat Interval(心跳间隔):默认 100ms,影响 Leader 选举超时和故障检测速度。 • Election Timeout(选举超时):默认 1000ms,集群分裂或网络分区时触发重新选举。 • 压测时若心跳间隔过短,会加剧 CPU 和网络开销;若过长,故障恢复变慢。 • 写入延迟 ≈ 网络 RTT × 2(Propose + Commit),与集群规模正相关。

2.2 键值存储模型:MVCC 与 Revision

etcd 采用多版本并发控制(MVCC)的键值存储模型。每个键的每次修改都会生成一个新的版本号(revision),旧版本数据不会立即删除,而是保留在后台等待压缩(Compaction)。

概念 说明 压测影响
Key 存储的键,支持前缀和范围查询 键长度和数量影响存储引擎 B+tree 的平衡效率
Value 与键关联的数据,最大 1.5 MiB(默认) 大 Value 导致网络带宽和磁盘 I/O 成为瓶颈
Revision 全局单调递增的版本号,每次事务递增 大量写入导致 revision 快速增长,Watch 事件流膨胀
Compact 删除指定 revision 之前的旧版本数据 压缩不及时会导致存储空间暴涨,查询性能下降
压测实践建议: 在压测前设置合理的 --auto-compaction-retention(如保留 5 分钟的历史版本),避免历史版本堆积导致磁盘写满或查询变慢。监控 etcd_server_slow_read_indexes_total 指标,若持续增长说明存储层压力过大。

2.3 Watch 机制:事件流与长连接

Watch 是 etcd 实现分布式协调的核心机制。客户端通过 gRPC 流式连接监听特定键或前缀的变化,etcd 服务端在键值变更时推送事件。Watch 机制在压测中极易成为瓶颈,因为每个 Watch 都会占用服务端内存和 goroutine 资源。

Watch 事件推送流程 Client gRPC Stream WatchableStore KV Store Watch(key) 注册 监听 事件通知 事件推送 事件流 Watch 压测风险与优化 • 每个 Watch 在服务端维护一个 goroutine 和事件缓冲区,大量 Watch 会耗尽内存。 • 事件堆积:若客户端消费慢,服务端缓冲区(默认 128 事件)满后丢弃事件,导致客户端重连。 • 优化方向:使用前缀 Watch 替代逐个 Watch;设置合理的 --max-request-bytes 和 --max-watchers-per-cluster。 • 监控指标:etcd_server_watch_events_total 和 etcd_server_watcher_count。

2.4 Lease 机制:心跳与存储关联

Lease(租约)是 etcd 实现分布式锁和服务注册的核心机制。客户端创建一个 Lease 并设置 TTL(生存时间),然后可以将多个键绑定到该 Lease 上。客户端需要定期续约(KeepAlive),否则 Lease 到期后所有关联的键会被自动删除。

组件 行为 压测关注点
Lease 创建 客户端指定 TTL,服务端创建 Lease 对象 大量 Lease 创建会消耗内存和存储
KeepAlive 客户端定期发送心跳续约 心跳频率过高导致服务端 CPU 和网络压力
Lease 过期 TTL 到期后,Lease 及关联键被删除 大量 Lease 同时过期引发删除风暴,影响写入性能
键绑定 一个 Lease 可绑定多个键 绑定大量键时,Lease 过期导致批量删除,产生大量事件
压测避坑: 避免在压测中创建大量短 TTL(如 1 秒)的 Lease,这会导致服务端频繁触发过期检查和删除操作,形成“心跳风暴 + 删除风暴”的双重压力。建议 TTL 不低于 5 秒,并合理控制 Lease 总数(监控 etcd_server_lease_expired_total)。

2.5 四大机制协同关系

在压测场景中,Raft、KV 存储、Watch、Lease 并非独立运行,而是相互影响:

  • 写入路径: Client → Raft Leader → 日志复制 → KV Store 写入 → 触发 Watch 事件推送 → 更新 Lease 关联键。
  • 压力传导: 高并发写入导致 Raft 日志复制延迟增加 → KV Store revision 快速增长 → Watch 事件队列堆积 → Lease KeepAlive 响应变慢 → 客户端重试加剧压力。
  • 限流切入点: 针对每个环节的瓶颈,etcd 提供了对应的限流参数(如 --max-txn-ops、--max-request-bytes、--max-watchers-per-cluster、--lease-recheck-interval),后续章节将逐一展开。
核心记忆点: Raft 决定写入延迟的下限,KV 存储决定容量和查询效率,Watch 决定事件推送的吞吐,Lease 决定分布式锁的可靠性。压测调优的本质是在这四个维度之间找到平衡点。