◈ DB 选型参考
← 返回首页

etcd

KV · 宽列 · 文档 #KV #Raft强一致 #K8s元数据底座 #配置中心 #分布式协调 #CNCF毕业 #开源

CNCF 毕业的分布式 KV 存储,Raft 强一致,主打元数据 / 协调 / 配置场景——Kubernetes 的元数据底座。"无聊的可靠性"本身:把野心限制在元数据,它几乎不背锅;把野心放到数据面,它的每个设计约束都会变成你的故障复盘标题。

用 AI 深挖这款:
证据等级:官方文档 厂商口径 社区实测 社区共识 待验证

基本信息

项内容
厂商CNCF(原 CoreOS 发起)
国家美国(开源社区)
起源2013 年 CoreOS 为容器集群协调而创建;2018 年 CNCF 毕业
许可证Apache-2.0,纯开源,无官方商业版、无功能阉割
托管服务无官方托管;随各云厂商托管 K8s 内含
主类型KV(分布式、强一致)
兼具类型变更流(watch)、分布式协调原语(lease、分布式锁)
数据模型key-value,单 value 建议 KB 级;单请求 ≤1.5MB
一致性模型强一致(Raft 线性一致);CP 系统
复制协议Raft(etcd-io/raft 独立库)

硬维度(47 项)

1 静态加密 / TDE 无(查证为无)

etcd 本体不提供任何静态加密:bbolt 数据文件、WAL、快照文件均为明文落盘。Kubernetes SIG 2019 年安全审计明确写"not encrypted at rest",加密职责上移到 kube-apiserver 层的 EncryptionConfiguration(aescbc/aesgcm/KMS v2 插件)。 选型含义:把 etcd 当通用 KV 用、且数据敏感时,必须自己在应用层加密或依赖磁盘加密;etcdctl snapshot save 产出的快照是明文 bbolt 文件,备份外泄=数据外泄。

2 TLS / 传输加密 有

client 与 peer 通信均可配置 TLS,可开 mTLS(--client-cert-auth,以客户端证书 CN 作为用户名参与认证)。v3.6.13/3.6.14 连续修复了 CRL 绕过(GHSA-3wh4-j44w-pg92)与 TLS 握手无 deadline 导致 goroutine 耗尽的 DoS(GHSA-6vch-q96h-7gc3)。 机制一句话:Go 标准 TLS 栈,证书热加载支持有限,生产必须配齐双向 TLS,否则"拿到证书=拿到全部数据"。

3 审计 无(查证为无)

etcd server 自身没有审计日志功能:谁在何时读写了哪个 key,etcd 不记录。K8s 场景的审计靠 kube-apiserver 的 audit log。 选型含义:合规要求操作留痕时,etcd 只能依赖前置代理/网关或主机层审计,原生能力是空白。

4 认证与权限 部分支持

有 RBAC:user/role 模型,权限粒度为 key 范围(range)读写,认证方式为密码或 TLS 客户端证书 CN;root 用户为超级用户,需先建 root 再 etcdctl auth enable。 缺口:① 默认关闭,K8s 默认部署也不启用(靠网络隔离+证书);② 粒度只到 key 前缀,无字段级、无行级;③ 无 LDAP/OIDC 原生集成;④ 权限绕过出过 CVE(嵌套 Txn 绕过 RBAC 检查 CVE-2026-33343,v3.5.28 修复;watch 越权 GHSA-xg4h-6gfc-h4m8,v3.6.14 修复)。 机制一句话:鉴权在 v3rpc 层按 key range 做允许/拒绝判断,简单但粗。

5 备份恢复 部分支持

备份:etcdctl snapshot save 在线对单成员取一致性快照。恢复:v3.6 起 etcdctl snapshot restore/status 已移除,改由 etcdutl 承担离线恢复;恢复本质是停机重建——用快照起一个新集群(或作为新成员加入),不支持在线单 key/表级恢复、不支持 PITR。恢复速度取决于快照大小与成员重放 WAL 的速度。 机制一句话:快照=bbolt 文件拷贝级备份,恢复=重建集群,没有逻辑备份/增量备份概念。

6 可观测性 有

/metrics 暴露 Prometheus 指标(--metrics=extensive 开全量:Raft、WAL fsync、mvcc、watcher 等);etcdctl endpoint health/status 看成员健康与 db 大小;etcdctl check perf 做写入压测;3.6 新增 /livez /readyz(对齐 K8s 探针语义)与 Kubernetes 风格 feature gates;--enable-pprof;3.6 引入 OpenTelemetry 追踪。 关键指标:etcd_disk_wal_fsync_duration_seconds p99(>10ms 即危险)、etcd_server_leader_changes_seen_total、dbSize/dbSizeInUse。

7 连接模型 有(gRPC 长连接)

2379 端口 gRPC(HTTP/2 多路复用),单连接承载多 stream;clientv3 支持多 endpoint 配置与 round-robin 负载均衡、断线重连;watch 是长生命周期 server-stream。连接开销低,不需要也不建议应用层连接池(一个 client 实例复用即可)。 注意:watch 数量直接转化为服务端内存与 fanout 开销(见深水区二)。

8 事务与隔离级别 部分支持(KV 语义的事务)

etcd 的"事务"= Txn:If(多条件比较)/Then/Else 原子执行,单 Raft round-trip 内对多 key 做 CAS(比较维度:value/version/createRevision/modRevision/lease)。 隔离级别:写一律线性一致(经 leader + quorum + WAL fsync);读分两档——linearizable(默认走 quorum/ReadIndex)与 serializable(leader 本地读,可能读到旧值但不加延迟)。 没有多语句交互式事务、没有回滚段、没有关系型意义上的隔离级别矩阵;客户端 STM(如 Go concurrency 包、Node 的 microsoft/etcd3 的 software transactional memory)是基于 Txn 在客户端拼出的乐观并发,不等同于服务端事务。

9 复制与一致性 有

Raft(etcd-io/raft 独立库):所有写经 leader 写 WAL 并 fsync 后复制到多数派才提交;CP 系统,分区时少数派侧写不可用、线性一致读失败,不存在脑裂写。读优化:leader 租约读(lease-based read)避免每次读都走 quorum。成员变更走 Raft conf change,支持 learner(无投票权、追上日志后转正)实现安全加节点。

10 扩展方式 无分片、无横向写扩展

官方推荐 3 或 5 成员,最多 7(再多收益递减、延迟上升);无分片、无横向写扩展——加成员不增加写吞吐,反而增加 quorum 延迟。扩容=加成员(在线,经 learner),是可用性扩容不是容量扩容。容量靠纵向:调大 --quota-backend-bytes(默认 2GB,建议上限 8GB,超 8GB 启动告警)。部分支持。

11 兼容性 有(v3 API 稳定;v2 已移除)

v3 gRPC API 为稳定接口;v2 API/v2store 在 3.6 被移除(--enable-v2 删除,残留非成员数据会拒绝启动),3.7 彻底删除 v2 代码。客户端生态:Go clientv3(官方)、Java jetcd、Python(python-etcd3 等)、Node microsoft/etcd3、Rust etcd-client。 迁移注意:3.5→3.6 混跑期间以 3.5 特性集为准;K8s apiserver 对 etcd 3.5/3.6 均有支持矩阵要求(以 K8s 官方矩阵为准,待验证具体版本对应)。

12 许可证与商业模式 有(纯开源)

Apache-2.0,CNCF 毕业项目,无官方商业版、无功能阉割。商业模式=云厂商托管 K8s 内含 + 生态公司运维支持。 选型含义:不存在"企业版才有 TDE/审计"这类差异,缺的能力是真缺,不是付费能解锁的。

13 中文资料丰富度 中等偏低|社区共识

官方文档英文为主;有社区中文翻译项目但版本滞后;中文博客/书籍多集中在"K8s 运维中的 etcd"(备份、compact、调优),对其 Raft/MVCC 源码级机制的中文深度资料少。低于 MySQL/PG/Redis 的中文生态。

14 性能与延迟特征 有

  • 写经 Raft 走主节点,单集群写入通常万级 QPS 以下;读可走 follower/learner 扩展 官方文档。
  • 不是数据面数据库:value 建议 KB 级,不要当通用 KV 用 社区共识。
  • 磁盘 fsync 延迟直接决定写延迟,盘是第一性能件 社区共识。

15 合规与认证 无

  • etcd 是 CNCF 毕业项目,无官方合规认证 社区共识。
  • 合规责任在使用 etcd 的平台/产品方(如各云厂商托管 k8s)社区共识。

16 成熟度与社区生态 有

  • 2013 年由 CoreOS 发布;2020 年 CNCF 毕业 社区共识。
  • Kubernetes 的默认元数据存储,间接装机量极大 社区共识。
  • 治理中立,长期维护有保障;但功能演进保守 社区共识。

17 标杆用户 有

  • 所有 Kubernetes 集群默认用 etcd 存元数据(公开)社区共识。
  • 直接把 etcd 当业务 KV 用的公开案例少 社区共识。
  • 云厂商托管 k8s behind the scenes 大规模使用 社区共识。

18 生态工具链 部分支持

  • 备份:etcdctl snapshot save/restore,简单可靠 官方文档。
  • 无 CDC/迁移工具概念(KV 语义简单);监控:Prometheus metrics 内置 官方文档。
  • 工具链薄是定位决定的,不是缺点 社区共识。

19 云托管与 Serverless 部分支持

  • 无官方托管服务 社区共识。
  • Aiven 等第三方提供托管 etcd 社区共识。
  • 实践中多随 Kubernetes 托管版间接使用 社区共识。

20 数据接入与摄入 不适用

  • etcd 存配置/元数据 KV,不是数据平台,无批量导入工具 官方文档。
  • 数据恢复靠 snapshot restore,不是摄入通道 官方文档。

21 外部数据访问 不适用(无查询引擎,无外部数据访问概念)

  • KV API 只读写自身数据,无联邦查询/外部表 官方文档。

22 CDC 与下游同步 部分支持

  • Watch API 提供 key 前缀/范围的变更通知,可做轻量订阅 官方文档。
  • 无变更日志持久化、无 exactly-once 语义,不等于 CDC 社区共识。
  • 历史版本可通过 revision 回看,但保留期有限 官方文档。

23 TTL 与数据生命周期管理 有(key 租约(lease)TTL,

  • key 可绑定 lease,lease 过期则 key 自动删除,是原生设计 官方文档。
  • lease 需客户端 keepalive 续约,网络分区时可能误删 社区共识。
  • 定位是元数据/配置存储,不适合海量业务数据过期 社区共识。

24 在线 DDL 与 Schema 演进 不适用

  • 纯 KV,无表结构,无 DDL 概念 官方文档。
  • "schema" 只存在于应用层:key 前缀划分命名空间、value 编码格式的约定,数据格式变更由应用版本管理,与存储无关 社区共识。

25 多租户与资源隔离 不适用(元数据存储,无租户资源概念)

  • 定位是集群元数据/配置存储,无多租户资源隔离设计 官方文档。
  • quota 后端字节数是全局的,不是租户级 官方文档。

26 跨地域多活 不适用

  • Raft 强一致要求低延迟,跨区部署延迟爆炸 官方文档。
  • 定位是单 region 集群元数据存储 社区共识。

27 高可用架构与 RTO/RPO 有(Raft 选主,秒级恢复)

  • Raft 多副本,leader 故障秒级重选,RPO=0 官方文档。
  • 推荐 3/5 节点,偶数节点无意义 官方文档。
  • 磁盘延迟是 leader 选举抖动常见根因 社区共识。

28 行级安全与数据脱敏 无(KV存储,无行列安全概念)

  • etcd 是分布式 KV 存储,无行 / 列概念,原生无 RLS、列级权限与脱敏 官方文档
  • RBAC 只到 key 前缀 / 范围级别,是唯一的隔离手段 官方文档
  • 敏感值只能靠客户端加密 社区共识

29 JSON 与半结构化能力 不适用(KV 字节值,无 JSON 语义)

  • value 为不透明字节,etcd 不解析 JSON(不适用)官方文档。
  • 如需 JSON 语义在客户端序列化/反序列化 社区共识。

30 全文检索能力 不适用(KV 无全文检索概念)

  • 无全文检索概念(不适用)官方文档。
  • 键前缀查询(prefix/range)是其检索方式 官方文档。

31 存储效率与压缩 部分支持

  • 底层 bbolt 为 B+tree 结构,无数据压缩机制,快照文件体积较大。官方文档
  • 快照与 WAL 保留策略可配置以控制磁盘占用,但属运维手段而非压缩。官方文档
  • 元数据场景数据量小,压缩缺失影响有限;大数据量场景不建议用 etcd。社区共识

32 开源协议与厂商锁定风险 无

  • etcd 采用 Apache 2.0 开源,为 CNCF 毕业项目,社区治理成熟。官方文档
  • 无协议变更黑历史;作为 Kubernetes 默认元数据存储,生态绑定的是开放标准而非厂商。社区共识
  • 任何兼容实现均可替换,无商业锁定。社区共识

33 查询优化器与计划稳定性 不适用(KV 存储无查询优化器)

  • 纯 KV 读写,无查询计划概念 官方文档。

34 参数调优与自治能力 部分支持(参数少:配额与压缩是调优点)

  • 参数精简,核心是 backend quota、compaction 周期 官方文档。
  • 大 value/高频 watch 是典型调优场景 社区共识。

35 静默数据损坏防护 部分支持

  • 底层 bbolt 仅元数据页带校验,数据页无页级 checksum,损坏可能静默。社区实测
  • etcd 有实验性的损坏检测与告警(如 corrupt check),但覆盖有限。官方文档
  • 生产实践多靠 quorum 多数派 + 快照重建坏成员,而非页级自愈。社区共识

36 存储过程/触发器/过程语言 不适用(KV 无过程语言概念)

  • 无存储过程/触发器概念(不适用)官方文档。
  • 事务为多 key 原子 compare-and-swap,非过程逻辑 官方文档。

37 约束与数据完整性 不适用(KV 无约束概念(不适用))

  • 无外键/CHECK/唯一约束概念(不适用)官方文档。
  • 一致性靠 Raft 与租约(lease),非数据完整性约束 官方文档。

38 分析 SQL 完备性 不适用(KV 无 SQL/分析概念)

  • 无 SQL,更无分析 SQL(不适用)官方文档。
  • 运维分析靠监控指标而非查询 社区共识。

39 被遗忘权与数据擦除 部分支持

  • etcd 是 MVCC 存储:删除只是追加 tombstone 修订,旧版本在压缩(compaction)前仍可读 官方文档
  • 需定期 compaction + defrag 才能物理回收;后端 bbolt 文件历史页可能残留 社区实测
  • 快照备份保留被删数据的历史状态 社区共识
  • 无擦除证明 社区共识

40 数据血缘与目录集成 不适用(KV 元数据存储,无血缘概念)

  • 定位是分布式 KV/配置中心,无数据血缘概念 官方文档。

41 存算分离 vs 存算一体 有

  • Raft 共识 + bbolt 本地存储,典型存算一体 官方文档。

42 多模能力 无(纯 KV,无多模)

  • 仅 KV 模型 官方文档。

43 FinOps 成本可观测性 不适用(基础设施组件,无计费概念)

  • etcd 是 Kubernetes 等系统的基础设施组件,无内置计费,成本并入集群硬件与运维人力。社区共识
  • 托管 Kubernetes 服务的控制面成本通常打包在集群费用中。厂商口径

44 驱动与多语言生态 有

  • gRPC API,官方 Go/Java/Python 客户端 官方文档。
  • 无 JDBC/ODBC(KV 定位不需要)社区共识。

45 物化视图 不适用(KV 无物化视图概念)

  • 无物化视图概念(不适用)官方文档。
  • 缓存/配置场景不需要预聚合 社区共识。

46 支持跨云 有

  • 开源 CNCF 项目,任意环境可部署 官方文档。
  • 跨云部署无意义(Raft 延迟敏感),单云/单区是常态 社区共识。

47 热点数据更新能力 部分支持

  • 并发控制原语是 Raft 全局串行写 + MVCC:所有写经 leader 提交后按全局 revision 顺序应用,每 key 保留多版本;同一 key 的并发写不存在"冲突"概念,只有先后顺序,无锁等待、无 abort、无需重试(重试归属:不适用,串行化消除了冲突)。需要 CAS 语义时用 Txn 的 If/Then 对 mod_revision 做比较,条件失败整体返回、由应用按业务语义决定是否重试。衰减不来自冲突,而来自版本堆积。无内置冲突检测机制(设计使然)官方文档。
  • 衰减形态:每次写(哪怕同一 key)都产生新全局 revision、bbolt 新条目,并经 Raft 多数派 fsync 落盘;热点 key 高频更新使该 key 的版本链与 bbolt 持续膨胀,历史 revision 读与压缩成本上升;后端配额默认 2GB(--quota-backend-bytes,官方建议上限 8GB)耗尽即触发 NOSPACE 告警、整个集群转只读,且删除数据后仍只读,必须人工 compact + defrag + 清告警才能恢复。单点瓶颈是 leader 单机磁盘 fsync 能力(约万级写/秒量级),加节点不加写吞吐官方文档。
  • 内置缓解(有限):未找到官方命名或文档化的热点识别、限流、打散或排队化机制的证据(不是查证为无);自动压缩(--auto-compaction-mode=revision/periodic,3.x 即有)定期丢弃旧版本,属于卫生机制而非热点打散——不压缩的后果就是配额耗尽转只读。应用层模式:高频计数器、事件流等热点数据按设计定位就不应进 etcd(它是低频协调状态存储),必须进时用 lease 做短暂 key、单 value 不超过 1.5MB(--max-request-bytes,超限直接拒绝),代价是把业务状态搬到消息队列或时序库的架构成本待验证。
  • 边界:watch 热点 key 的客户端会被每次更新唤醒,热点写放大为通知风暴,慢消费者拖慢整体,背压由应用层处理(内核无背压排队);磁盘变慢会导致 leader 心跳超时、频繁选主,写延迟从毫秒级跌到秒级——协调代价随争用超线性增长。重试归属:watch 断开由客户端重连,写失败由应用重试。应用层模式:热点 key 的 watcher 侧做聚合节流(代价:通知实时性下降);生产实践建议:单 key 高频更新建议控制在约 1000 QPS 以内(待验证:整体写速率的稳定性指引有社区出处,单 key 口径尚无确切出处),超限则 revision 膨胀与压缩成本急剧上升社区共识。

招牌能力

  1. Revision 语义的变更流:全局单调 revision + 任意历史位点 watch,是"天然 CDC"。竞品(Redis stream/ZK watch)要么没全局序,要么 watch 语义弱。这是 etcd 当配置中心/服务发现底座的真正壁垒。
  2. Lease(TTL 心跳)原语:key 绑定租约、过期自动删,分布式"心跳-故障检测"不需要应用层轮询。K8s node lease、分布式锁、选主全 built on this。
  3. Raft 强一致 + 3 节点开箱即用:不调优就有线性一致,运维心智负担远低于"最终一致+冲突解决"系统。代价是写吞吐天花板低——这是 trade-off,不是缺点。
  4. Txn CAS:单 round-trip 多 key 原子比较交换,无锁乐观并发的原子原语,锁/屏障/队列配方都从这里长出来。

深水区

深水区一(一致性/可用性):Raft 实现与选主——"1 秒的沉默税"

  • 机制:leader 每 100ms(--heartbeat-interval,默认)发空 AppendEntries 心跳;follower 超过 1000ms(--election-timeout,默认,实际随机化到 1000–2000ms)没收到心跳即发起选举。写路径:client→leader→WAL 落盘 fsync→复制到多数派→apply 到 bbolt→返回。读分 linearizable(走 ReadIndex/quorum 确认仍是 leader)与 serializable(本地直接读)。
  • 推到边缘:① leader 进程被 kill:写停顿至少 1 个选举超时,实测干净故障下 1–3 秒写不可用,分裂投票时 5–10 秒;② 更常见的是"假死":磁盘 fsync 毛刺 > election timeout → follower 误判 leader 死亡 → 频繁选主(leader_changes 暴涨),apiserver 写抖动、watch 重连风暴。有生产 runbook 记录 leader 在写负载下连 100ms 心跳都发不出,被迫把心跳调到 250ms/选举调到 2500ms 止血——治标,病根是控制面磁盘 sync 写延迟。③ 脑裂分区:少数派侧写直接失败,不会产生分叉数据,这是 CP 的代价也是价值。
  • 选型含义:etcd 的可用性下限由磁盘 fsync 决定,不是 CPU/内存。把它和 I/O 密集型应用放同一块盘,等于给选主定时器埋雷。
  • 来源:官方 tuning 文档(100ms/1000ms 默认值);社区 runbook(心跳失败 499 次/6h 实测);OpenShift etcd 性能文档(磁盘延迟→丢心跳→选主链条)。

深水区二(性能边缘):watch 机制与大规模 watch 的压力——"变更流是免费的,直到它不是"

  • 机制:watch 是服务端保持的 gRPC 长流;每个 watcher 按 key range 注册,服务端按 revision 顺序 fanout 事件;支持从任意历史 revision 起播(MVCC 赋予的能力);客户端可发 progress 请求保活。watch 事件走 mvcc 的事件队列,每个 watcher 有独立缓冲。
  • 推到边缘:① watcher 数量:官方口径"典型 <1 万,测试过 10 万+"(第三方整理,待验证官方原文);内存随 watcher 数 × key churn 线性涨,bbolt mmap 之外再叠 watcher fanout,内存常为 db 文件的数倍(OpenShift 文档明确"完全正常")。② K8s 放大器:每个 kubelet/apiserver informer 都是 etcd watcher,大集群下 apiserver 的 list+watch 风暴直接打到 etcd;曾有 AKS 级案例:API 负载→etcd 内存超 20GiB 告警→级联劣化。③ 语义坑:从已被 compact 的 revision 起 watch 会直接失败(ErrCompacted),客户端必须重建 watch 并全量 list——client-go 的 watch 重连+resync 逻辑就是为这个擦屁股;v3.6.2 刚修过"watch 未来 revision 返回旧事件"的 bug。
  • 选型含义:把 etcd 当"配置中心推送底座"很香,但 key churn 高 × watcher 多时,先算内存账再算功能账;auto-compaction 保留窗口必须大于最慢消费者的 watch 延迟,否则消费者永远在"重建-全量-再被 compact"里打转。
  • 来源:etcd 官方 FAQ(compact 后 watch 语义);OpenShift cluster-etcd-operator 性能文档;v3.6.2 Changelog(watch bug 修复);Azure AKS 故障排查文档(etcd 内存告警案例)。

深水区三(运维/存储):MVCC 修订版本与 compact/defrag——"只增不减的账本"

  • 机制:每次写(put/delete)全局 revision+1;每个 key 保留多代版本(keyIndex:generation→revision 列表);历史版本用于 watch 回放与历史读。compact 删除指定 revision 之前的旧版本(只标记内部可复用,不归还磁盘空间);defrag 重写整个 bbolt 文件才真正把空间还给 OS。K8s apiserver 默认每 5 分钟 compact 一次、保留 10 分钟窗口。
  • 推到边缘:① 不 compact:MVCC 历史随写入量线性膨胀(不是数据量),bbolt 文件顶到 --quota-backend-bytes(默认 2GB)→ 触发 NOSPACE alarm → 全集群拒绝一切写,kubectl apply 全部报 etcdserver: mvcc: database space exceeded,控制面"冻住"。恢复三件套:compact→逐成员 defrag→alarm disarm,缺一不可。② defrag 本身阻塞该成员的读写,必须逐个成员滚动做;v3.6.5 修复了"applySnapshot 与 defrag 并发导致潜在数据损坏"——说明 defrag 路径历史上真出过损坏。③ 碎片常态:db 文件 4–8GB 而 live 数据仅 2GB 是常见现象,dbSize - dbSizeInUse > 40% 就该计划 defrag。
  • 选型含义:etcd 的运维核心就两件事——compact 策略 + 磁盘水位。auto-compaction 不是可选项,是生存项;监控必须看 dbSizeInUse 而不是文件大小。
  • 来源:etcd 官方 FAQ("mvcc: database space exceeded" 词条);v3.6.5 Changelog(快照/defrag 并发损坏修复);社区 etcd 运维资料(NOSPACE 恢复流程)。

深水区四(扩展/容量):单集群规模上限与"扩容悖论"

  • 机制:硬性边界——单请求 ≤1.5MB(--max-request-bytes);backend 配额默认 2GB、建议上限 8GB(超 8GB 启动告警,性能退化自负);成员数 3/5 最佳、7 为实际上限。内存:全 key 的内存 B-tree 索引常驻(约每 key 百字节级,百万 key 约数百 MB 量级,社区估算)。
  • 推到边缘:① 2 成员集群不如 1 成员:quorum=2,一个挂就全挂,容错为 0 却付了复制的延迟税——新手最常见的拓扑错误。② 加成员≠扩容:5→7 成员,quorum 从 3→4,写延迟上升、吞吐下降,换来的是多容 1 台。想要更高写吞吐,etcd 给你的答案是"换更快的盘",不是"加节点"。③ 8GB 之上:官方只说"建议别超",超了之后 mvcc 索引/watcher 内存、defrag 时间(重写 8GB+ 文件)都会变成运维噩梦;真到这一步,正确动作是拆 key 空间/降 churn,不是调大配额。
  • 选型含义:etcd 是纵向扩展系统,容量规划=磁盘配额+内存+fsync 三者的木桶。把它当通用 KV 存大 value/高吞吐写,是选型错误,不是调优问题。
  • 来源:官方 system limits 文档(2GB/8GB/1.5MB);官方 FAQ(奇数成员与 quorum 解释);社区容量规划资料。

深水区五(故障/恢复):K8s 大规模集群下的 etcd 故障模式

  • 机制:K8s 把所有集群状态(pod/spec/secret/lease/events)押在 3–5 个 etcd 成员上;apiserver 是 etcd 唯一重客户端(外加 controller 的 lease 心跳)。
  • 推到边缘的真实模式:① 慢盘型:云盘 IOPS 被邻居挤占→WAL fsync p99 从 5ms 飙到 50ms+→etcd_disk_wal_fsync_duration_seconds 告警→频繁选主→apiserver 写超时→kubectl 卡顿。Azure AKS 官方排障文档把"etcd 慢"列为 apiserver 故障的独立根因大类。② 空间型:events/CRD 失控写入(如话痨 operator 每秒刷 events)→ MVCC 膨胀→NOSPACE→全集群只读。K8s 把 events TTL 设为 1 小时,本质就是给 etcd 擦屁股。③ 内存型:大集群全量 list(列出所有 pod)→ apiserver/etcd 内存尖刺→OOM 级联。OpenShift 文档点名"list all pods in large cluster"是 etcd 内存杀手。④ 人为型:etcdctl defrag --cluster 全集群一起做、快照恢复时新老集群 peer 地址混淆(官方 FAQ 警告"不同集群 peer 地址必须不相交")。
  • 选型含义:etcd 故障的 blast radius = 整个 K8s 控制面。生产 checklist 收敛为四条:独立 SSD(fsync p99<10ms)、quota 显式设 8GB、auto-compaction 必开、watch/list 限流。
  • 来源:Azure AKS apiserver/etcd 排障官方文档;OpenShift etcd 性能文档;etcd 官方 FAQ;社区故障诊断手册。

客户经验

内核 Kubernetes 控制面的"唯一真相源":Raft 强一致 + MVCC watch

一句话
为"小数据、强一致、高可靠的协调"而生的分布式 KV:Raft 保证线性一致,MVCC revision + watch 让 k8s 的 controller 模式(list-watch)成为可能;它是"选主/配置/服务发现"的标准答案,不是通用 KV。
窄场景
集群元数据与协调状态——k8s 的所有资源对象、controller 选主 lease、服务发现;数据量小(GB 级)、读多写少、丢一条都不行。任何跑 k8s 的团队被动拥有,几乎不用选型。
机制
两层机制锁死这个生态位——① Raft:leader 处理所有写、多数派确认后才提交,天然线性一致;② MVCC:每次写递增全局 revision,watch 可以带 revision 断点续传——k8s apiserver 的 watch 缓存、controller 的 resync 全靠这个语义。官方 FAQ 的原话:leader 的存活本身就绑定在"能否及时 fsync"上,宁可丢 leader 也不接受一个"看起来活着但提交不了"的 leader。
生产验证
全球每一个生产 k8s 集群的控制面都跑在 etcd 上,这是最大规模的生产验证(社区共识级)。官方 FAQ 对"为什么磁盘抖动会丢 leader"的解释是该设计哲学的第一手陈述(https://github.com/etcd-io/website/blob/HEAD/content/en/docs/v3.5/faq.md)。
竞品差距
31 款里没有同类(Consul/ZooKeeper 不在名单)。Redis 有 pub/sub 但无持久化、无 revision 语义,做选主是反模式;DynamoDB 有条件写可做分布式锁,但延迟与一致性语义不同且是云厂商绑定。
证据等级
社区共识(k8s 生态的既定事实)+ 官方文档。诚实备注:官网吹的是"reliable distributed key-value store",厂商和用户一致;错位在反方向——很多人误把它当通用 KV 用。
最后核验
2026-10-01

避坑 写吞吐天花板 + fsync 偏执:"慢盘 = 丢 leader = 控制面抖动"

一句话
Raft 的每笔写都要先 fsync WAL 落盘,etcd 的写吞吐上限 ≈ 磁盘顺序 fsync 能力;leader 一次 fsync 超过 election timeout 就会被判定死亡触发重选,连锁导致 apiserver 超时、controller 丢选主 lease。
窄场景
这是上一张卡片的镜像代价——etcd 只适合"小数据、低写"的协调;任何想拿它当"高频写 KV"的想法都会撞上这块天花板。etcd 必须跑在本地 SSD 上,网络盘(iSCSI/NFS/云盘抖动)是生产事故之源。
机制
Raft 安全性的根基是"提交前先持久化日志",etcd 的写路径是 fsync-bound,不是 CPU-bound 也不是网络-bound。官方 FAQ 原话:"假设 leader fsync 一次要 1 分钟,而 election timeout 是 1 秒——即使它网络心跳正常,它实际上已经不可用了;这是故意设计的"。故障链是教科书式的:WAL fsync 变慢 → Raft 提案提交变慢 → 心跳不及时 → follower 发起选举 → 写停顿 → apiserver 请求超时 → controller/scheduler 的选主 lease 到期。连**维护操作本身**都会触发:defrag 时 leader 磁盘 I/O 暴涨、心跳延迟,follower 照样发起重选。
生产验证
hnatekmarorg/devops-cluster 的真实生产事故(2026-09-18):control plane 跑在 iSCSI 网络盘上,etcd 报 "apply request took too long"(118ms/138ms/350ms,期望 100ms),apiserver 返回 "etcdserver: request timed out",随后 karpenter-provider-proxmox panic、kube-controller-manager 与 kube-scheduler 相继丢选主 lease;修复是把 control plane 迁到本地盘——"etcd 要本地 fsync,worker 要容量"(https://github.com/hnatekmarorg/devops-cluster/commit/b3aea1d6848c5ad399501c628f8a6af2731bace8);社区共识的量化线:vember31/home-ops 的 runbook——etcd WAL fsync p99 正常 <10ms、10–25ms 降级、>25ms 危急(https://github.com/vember31/home-ops/blob/HEAD/docs/runbooks/cluster-investigation.md)。
竞品差距
Cassandra/ScyllaDB——无 leader、写可横向扩展,是"高频写"场景的答案,但无 Raft 级线性一致;Redis——快但无持久化一致性保证。
证据等级
社区实践(真实事故复盘)+ 官方文档(FAQ 第一手确认设计意图)。
最后核验
2026-10-01

避坑 MVCC 修订历史无上限:"database space exceeded"让全集群写冻结

一句话
etcd 默认永久保留所有 key 的历史 revision,bbolt 文件只涨不缩;触及 `--quota-backend-bytes`(默认仅 2GiB)时触发 NOSPACE alarm,全集群拒绝一切写——kubectl apply 全部返回 `etcdserver: mvcc: database space exceeded`,控制面"冻住"。
窄场景
任何高 churn 的集群(大量 CRD、频繁更新的 ConfigMap、大规模事件写入)且没开 auto-compaction 的,都会在几天到几周内撞上这堵墙。
机制
MVCC 是第一张卡片里 watch 断点续传的基础,但代价是历史 revision 默认永不过期;compact 只是标记旧 revision 可回收,bbolt 文件的空闲页要靠 defrag 才能真正归还(且 defrag 本身会抖动 leader)。默认值 2GiB 在今天动辄上千节点的集群里小得离谱,而官方建议上限是 8GiB——超过 8GiB 官方明确说"你先检查架构是不是有问题"。这是一个"默认配置即坑"的经典设计。
生产验证
whoismonesh/k8s-everything 灾难案例库 DC-1:"etcd 默认永久保留 revision 历史,几天 churn 后 DB 胀到数 GB 而 compaction 从未配置",修复为 compact + 逐个 defrag + 开 `--auto-compaction-retention`(https://github.com/whoismonesh/k8s-everything/blob/HEAD/14-troubleshooting/disaster-cases.md);velstra/cloud 的真实 outage(2026-09-02,commit 022f9674):"etcdserver: mvcc: database space exceeded"——默认从不 compact,revision 历史把 store 胀到 2.4GB 撞上 2GiB quota;compact+defrag 后回到 368MB,"it was history, not data"(https://github.com/velstra/cloud/commit/022f96747dfa)。
竞品差距
Redis——无 MVCC 历史,无此问题(但也无 watch 语义);其余 MVCC 系(PostgreSQL 等)有 vacuum/autovacuum 自动回收,etcd 的"默认不回收"是异类。
证据等级
社区共识(事故编目 + 真实 outage,机制一致)。诚实备注:官方运维指南确实写了 auto-compaction 和 defrag,但它是"运维指南"不是"默认行为"——用户第一次听说 compaction 往往是在生产冻结之后。这是"文档里有"和"默认安全"之间的经典鸿沟。
最后核验
2026-10-01

用户最买账的 5 点

  1. "K8s 选中它"带来的信任 机制:Raft 线性一致 + 长期生产验证。价值:选型免举证。 边缘/失效条件:这种信任常被误读为"etcd 适合一切 KV 场景",大 value/高吞吐一上就翻车。
  2. Watch 推送范式 机制:长连接 fanout + revision 回放。价值:配置变更秒级触达、无轮询。 失效条件:watch 断在 compact 位点后必须全量重建,消费者必须实现重连+resync。
  3. Lease 心跳 机制:TTL + keepalive 自动续约。价值:节点/进程存活的权威信号。 边缘:网络分区时 lease 续不上会误判死亡(K8s node NotReady 经典 case),续约间隔与网络质量强相关。
  4. 单二进制、运维简单(小规模) 机制:无外部依赖、3 节点 Raft。价值:小团队也能 hold 住。 边缘:规模/负载上去后,"简单"的反面是"可调参少",到 8GB/高 churn 就是另一套运维。
  5. gRPC API + 多语言客户端 机制:protobuf 强契约。价值:嵌入各类控制面。 边缘:v2→v3 的 API 断代史提醒:跟紧大版本,3.6 删 v2 store 是前车之鉴。

吐槽清单

#吐槽影响版本状态
1默认 2GB 配额,顶满后 NOSPACE 全集群拒绝写,控制面冻结全版本open(设计如此;v3.6.3 优化了配额 flag 的帮助文案,治标)
2无原生静态加密:数据文件/WAL/快照全明文全版本open
3无审计日志:谁读写了 key 无从追溯全版本open
4在线 defrag 阻塞该成员读写,需逐成员滚动全版本open
5快照恢复=停机重建集群,无在线/PITR/单 key 恢复全版本open
6写不能水平扩展,加成员反而降写吞吐全版本open(架构约束)
7watch 鉴权绕过:有单 key 读权限可收到该前缀所有 key 的 watch 事件≤v3.6.13/≤v3.5.32fixed-in-v3.6.14(GHSA-xg4h-6gfc-h4m8)
8嵌套 Txn 绕过 RBAC 鉴权检查v3.5.xfixed-in-v3.5.28(CVE-2026-33343;v3.6 是否曾受影响待验证)
9TLS 握手无 deadline,未认证连接可耗尽 goroutine 致 DoS≤v3.6.13fixed-in-v3.6.14(GHSA-6vch-q96h-7gc3)
10applySnapshot 与 defrag 并发造成潜在数据损坏≤v3.6.4fixed-in-v3.6.5
11watch 未来 revision 返回旧事件/通知≤v3.6.1fixed-in-v3.6.2
12磁盘慢=集群抖:fsync 毛刺直接触发选主,无缓冲余地全版本open(架构约束,靠硬件+调参缓解)
13内存可达 db 文件数倍(mmap+mvcc 索引+watcher fanout),OOM 风险隐蔽全版本open
14单请求 1.5MB 上限,大 value 场景天然不适配全版本open(设计约束)
15RBAC 粒度只到 key range,无 LDAP/OIDC,多租户场景捉襟见肘全版本open
16v2 API 在 3.6 被移除,老客户端/工具链有迁移成本v3.6open(迁移一次性)

判决

  • 用 etcd,当且仅当:① 数据是小规模元数据/协调状态(KB 级 key,总量 <8GB);② 需要强一致(选主、分布式锁、配置权威源);③ 需要 watch 变更流或 lease 心跳语义;④ 能接受"写吞吐不扩展、容量靠纵向"的天花板。K8s 元数据、服务发现、配置中心、分布式协调是它的主场。
  • 不要用 etcd,当:① 单 value 大(MB 级)或总量预期超 8GB;② 写吞吐要求随业务线性增长;③ 需要审计、静态加密、PITR 等企业合规能力(原生全缺);④ 需要复杂查询/二级索引。此时应看 TiKV/Redis/DynamoDB 等,而非调 etcd 参数。
  • 版本建议:新部署直接上 v3.6.x(≥v3.6.14)——拿 downgrade 支持、v3store 唯一真相源、livez/readyz 与当年累计的安全修复;3.4 已 EOL 必须迁走;3.5 用户按官方 checklist(先升 3.5.32+、清 v2store)再滚动到 3.6。
  • 一句话:etcd 是"无聊的可靠性"本身——把野心限制在元数据,它几乎不背锅;把野心放到数据面,它的每个设计约束都会变成你的故障复盘标题。

来源与待验证清单

① etcd raft 是否默认开启 pre-vote;② --max-concurrent-streams 等服务端流控 flag 默认值;③ v3.7 线 GA 后的 K8s 官方支持矩阵对应关系;④ watch 10 万级测试数据的官方出处原文;⑤ v3.6 是否曾受 CVE-2026-33343(嵌套 Txn 鉴权绕过)影响。

  • 官方文档 / 博客 / Changelog(证据等级"官方文档"):etcd 官方文档(tuning、system limits、FAQ)、v3.6.x Changelog(v3.6.2/v3.6.5/v3.6.14 安全与 bug 修复)、Kubernetes SIG 2019 安全审计
  • 社区运维资料("社区实测/社区共识"):OpenShift cluster-etcd-operator 性能文档、Azure AKS apiserver/etcd 排障文档、社区 runbook(心跳失败实测)、社区容量规划资料
  • 下次评审:跟踪 v3.7 线 GA 后的 K8s 支持矩阵;跟踪 CVE-2026-33343 在 v3.6 的影响确认;跟踪 watch 大规模测试官方出处