土法炼钢 · 系统与基础设施

【etcd】排障五轴:Raft/WAL/MVCC/Watch/Lease 口令表

文章导航

分类入口
distributedkubernetes
标签入口
#etcd#troubleshooting#raft#wal#mvcc#watch#lease#five-axes#v3.5.33

目录

「etcd 挂了」在工单里可能指五种互不相同的失败:Leader 丢失、WAL fsync 拖尾、quota 写拒绝、Watch 全量重同步、或 Node Lease 集体过期。一上来对所有节点 defrag,可能把 MVCC 轴 的维护窗口当成 Raft 轴 的 quorum 问题放大;在未确认 Leader 时对 follower 做破坏性 restore,则可能永久丢 quorum。

前序篇已分轴讲机制;本文是系列第 15 篇:症状 → 轴 映射与 etcdctl 字段语义。口诀不变:先点名轴,再下钻组件。K8s 耦合见 第 13 篇;运维动作见 第 14 篇。无 etcd 集群则不粘贴伪造 endpoint status 表格。

本篇在系列中的位置

篇目 核心内容
第 14 篇 · 运维与升级 member change、backup/restore
第 15 篇 · 排障五轴 Raft/WAL/MVCC/Watch/Lease 口令表
第 16 篇 · 选型收束 排除树、开放问题、边界关闭
系列目录 全部篇目

版本锚定:etcd v3.5.33(tag v3.5.33)。etcdctl endpoint status 列名以该版本 CLI 为准。distributed/50 的百科单篇可速览 Watch/MVCC;本篇坐标系仅指 etcd 生产内核五轴,不与 Istio/Linkerd 等同名五轴混用。


一、口诀与总图

轴 1 Raft 共识与成员   — Leader、term、index、learner、quorum、复制 lag
轴 2 WAL 持久化与恢复 — fsync、WAL 段、snapshot、committed vs applied、NOSPC
轴 3 MVCC 存储与容量  — Revision、treeIndex、bbolt、quota、compaction、defrag
轴 4 Watch 客户端同步 — start_rev、synced/unsynced、ErrCompacted、背压
轴 5 Lease TTL 与语义  — grant/KeepAlive/checkpoint、Leader 切换、Txn 锁边界

Raft lag 与 apply lag 分列:Raft index 涨而 applied index 停 → 优先 Apply/MVCC 轴;committed 不涨 → Raft/WAL 轴

flowchart TD
  symptom["Symptom"]
  symptom --> name["Name etcd axis first"]
  name --> a1["Axis1 Raft quorum"]
  name --> a2["Axis2 WAL fsync"]
  name --> a3["Axis3 MVCC quota"]
  name --> a4["Axis4 Watch rev"]
  name --> a5["Axis5 Lease TTL"]
  a1 --> drill["Drill component metrics logs"]
  a2 --> drill
  a3 --> drill
  a4 --> drill
  a5 --> drill

全链路位置见 第 1 篇PLAN.md §八。


二、症状 → 轴(入口表)

症状(入口) 优先轴 先查 不要先做
no leader / 选举风暴 1 网络分区、quorum 成员数、磁盘慢 defrag 全集群
写超时 / context deadline exceeded 1→2 Leader 是否存在;WAL fsync p99 升 quota
mvcc: database space exceeded 3 quota、db size;alarm 只 restart
读到的数据「旧」 1 或 8 是否线性读;是否 follower 读 换应用代码
Watch 断开 / controller 风暴 4 ErrCompacted;start rev 加 etcd 节点数
Node 批量 NotReady 5 Lease TTL;KeepAlive 查 Pod CNI
重启极慢 2→3 WAL 重放长度;db 大小 force-new-cluster
member 不可达 1 peer URL、防火墙 删 member 到 < quorum
apiserver 504(K8s) 分列 apiserver etcd 延迟 vs 本表 混因

默认顺序:轴 1 quorum → 轴 2 磁盘 → 轴 3 容量 → 轴 4 Watch → 轴 5 Lease。一次否证一轴。


三、轴 1:Raft 共识与成员

表象:集群不可写;etcdserver: no leader;Raft 选举频繁;follower RAFT INDEX 长期落后。

子问题 核对 工具/指标
Quorum 丢失 存活 voting member 是否 \(\leq \lfloor N/2 \rfloor\) member list、健康检查
Leader 网络隔离 Leader 能否连多数 peer RTT、丢包
慢磁盘拖复制 WAL fsync 高 → 轴 2 联动 etcd_disk_wal_fsync_duration_seconds
Learner 误当 quorum learner 无投票权 endpoint status ROLE
配置变更中途失败 最近 member add/remove Raft log / 运维记录

committed index vs applied index第 3、6 篇):

与 distributed/13 分工:PreVote、ReadIndex 代码走读 → distributed/13;本篇只问「是否 Leader、是否 quorum」。


四、轴 2:WAL 持久化与恢复

表象:进程 crash 后长时间 startingcorrupt WAL;磁盘满;snapshot 失败。

子问题 核对
WAL fsync 慢 云盘 IOPS、与别的进程争用;--wal-dir 是否 SSD
WAL 与 data 同盘 官方建议 WAL 与 backend 可分盘(B 级 hardware 文档)
Snapshot 卡住 --snapshot-count;db 过大
NOSPC 操作系统磁盘;非 quota alarm
restore 后 cluster ID 乱 是否混用 restore 与 live member

指标(语义,非阈值截图)

指标 含义
etcd_disk_wal_fsync_duration_seconds WAL 持久化延迟
etcd_disk_backend_commit_duration_seconds bbolt batch commit
etcd_server_proposals_failed_total Raft 提案失败计数

官方 hardware 文档给出 WAL fsync、backend commit 的 p99 告警参考(A 级)——具体毫秒数以 Hardware guidelines 为准,本站不固化「绿线」截图。


五、轴 3:MVCC 存储与容量

表象database space exceeded;alarm NOSPACE;读延迟升;defrag 后仍满;大 Value 写失败。

子问题 核对
Quota --quota-backend-bytes(默认 2GB,最大 8GB)
历史 rev 膨胀 auto-compaction 是否启用;retention
BoltDB 碎片 compact 后是否 defrag(第 12 篇
treeIndex 内存 key 数 × revision 历史
大 object(K8s) CRD/Secret 体积;接近 1.5MB 建议上限

alarm 处理顺序(语义):compact → defrag(维护窗)→ alarm disarm——详见官方 alarm 文档;不要在生产高峰对全集群同时 defrag

读旧 revision:Range 带 revision 参数读历史是 MVCC 特性;若业务「应读最新」却读到旧值,回到 第 8 篇 读一致性分列,不要与 Watch 轴混谈。


六、轴 4:Watch 客户端同步

表象:Watch 断流;etcdserver: mvcc: required revision has been compacted;apiserver/controller 大量 List;内存涨(unsynced watcher 追赶)。

子问题 核对
start rev 过旧 客户端 resourceVersion / Watch rev
Compaction 过 aggressive --auto-compaction-retention
unsynced 追赶 历史 rev 回放读 BoltDB(第 9 篇
gRPC 流背压 客户端消费慢;channel 阻塞
K8s informer apiserver watch cache 是否也重 List

ErrCompacted 标准动作:全量 List 拿新 resourceVersion 再 Watch——无捷径。大集群成本是 开放问题第 16 篇 §三)。

与轴 3 关系:compaction 清历史 rev → 触发轴 4 失败;调 retention 是 联合调参,不是单轴旋钮。


七、轴 5:Lease TTL 与语义

表象:Lease 集体过期;分布式锁提前释放;K8s Node NotReady 雪崩;TTL「重置」。

子问题 核对
KeepAlive 停止 客户端 crash;网络
Leader 切换 TTL 是否 checkpoint(第 10 篇
时钟漂移 LeaseRead 与 Leader lease(读路径边界)
K8s Node Lease kubelet 续约;apiserver → etcd 写入
锁语义 Jepsen:Lease 锁非 strict-serializable(distributed/53

KeepAlive 不经 Raft——Leader 故障时轴 5 与轴 1 同时亮;修复 Leader 后观察 Lease 是否 mass expire。


八、etcdctl 字段语义

以下解释 命令语义(A 级:etcdctl endpoint statusendpoint health 文档)。不粘贴本环境输出

8.1 etcdctl endpoint health

8.2 etcdctl endpoint status --write-out=table

常见列(v3;具体以 --help 为准):

字段 解读要点
ENDPOINT 目标 URL
ID 1 member ID
VERSION 运维 混合版本升级窗口
DB SIZE 3 当前 backend 大小
IS LEADER 1 是否 Raft Leader
IS LEARNER 1 learner 无投票
RAFT TERM 1 当前 term
RAFT INDEX 1 已提交日志位置(口径以文档为准)
RAFT APPLIED INDEX 1/3 已 apply 到 MVCC 的位置
ERRORS 任意 须展开日志

分列口诀RAFT INDEXRAFT APPLIED INDEX 持续拉大 → Apply/MVCC;两者都不涨 → Raft/WAL。

8.3 其它常用命令(语义)

命令 用途
etcdctl endpoint hashkv 各 member KV 哈希是否一致
etcdctl alarm list NOSPACE 等 alarm
etcdctl member list 成员与 learner
etcdctl get ... --rev= 读历史 rev(MVCC)

九、K8s 控制面对照

K8s 症状 先分列 再落 etcd 轴
apiserver 504 apiserver metrics 1–3
全 Node NotReady Lease + 网络 5 → 1
单 controller 停更 Watch/List 4
仅 Events 丢 events etcd 3(分集群)
升级后异常 升级窗 14 + 4(rev bump)

完整耦合见 第 13 篇


十、证据包写法

工单或 postmortem 建议 按轴贴证据,避免「etcd 日志一段」:

Axis1: endpoint status (Leader/term/index/applied)
Axis2: wal_fsync p99, disk free
Axis3: db size, quota, alarm, last compact
Axis4: compacted rev, client start rev, apiserver watch errors
Axis5: lease count, recent leader change, checkpoint flag

一次 incident 只验证一轴假设;否证后再换轴。


参考资料

规范 / 官方文档(A)

源码(A)

站内

实验台账


上一篇运维与升级

下一篇选型收束与开放问题

读完这篇,下一步读什么

优先读同系列或同问题的下一篇,把单篇消费变成主题集群。


By .