etcd 分布式一致性存储入门

知识库
知识库文档
/tech-stacks/etcd/tutorial/etcd 分布式一致性存储入门.md

文档

前言

如果你用过 Redis,你可能会问:"有了 Redis 为什么还要 etcd?"答案在于一个词:一致性。Redis 是 AP 系统(最终一致),而 etcd 是 CP 系统(强一致)。当你的分布式锁、选主、配置变更必须是"绝对正确"的时候,etcd 是答案。


第一章:理解 Raft

1.1 为什么需要共识算法

问题:3 个节点存储同一数据,如何确保所有节点返回相同值?

方案1:主从复制(MySQL)
  → 主写入,从复制。主挂 → 可能丢数据

方案2:Raft
  → 多数派(quorum)写入:3 节点中 2 个确认即成功
  → 保证:任何时刻,多数派中至少有一个节点有最新数据

1.2 Raft 三阶段

阶段1:Leader 选举
  所有节点 → Candidate → 获得多数票 → Leader
  心跳间隔:T(通常 100-500ms)

阶段2:日志复制
  Client → Leader → 写入日志 → 复制到 Follower → 多数确认 → 提交

阶段3:安全
  新 Leader 一定包含所有已提交的日志
  利用 Term(任期号)和 Index(日志索引)保证

1.3 Quorum 数学

N 节点集群需要 (N/2)+1 节点确认:

N=3 → 需 2 确认 → 容忍 1 节点故障
N=5 → 需 3 确认 → 容忍 2 节点故障
N=7 → 需 4 确认 → 容忍 3 节点故障

第二章:etcd 核心 API

2.1 KV 操作

etcdctl put /config/app/timeout "30s"
etcdctl get /config/app/timeout
etcdctl del /config/app/timeout
etcdctl get /config/ --prefix      # 前缀查询

2.2 Watch(长连接推送)

# 终端1:监听变化
etcdctl watch /config/ --prefix

# 终端2:修改值
etcdctl put /config/app/timeout "60s"

# 终端1 实时输出:
# PUT /config/app/timeout
# 60s

2.3 Lease(租约)

# 创建 30 秒租约
etcdctl lease grant 30
# lease 694d8f7a3b2e1c5d granted with TTL(30s)

# 用租约写 key(到期自动删除)
etcdctl put /services/app/instance1 "192.168.1.1:8080" --lease=694d8f7a3b2e1c5d

# 续约
etcdctl lease keep-alive 694d8f7a3b2e1c5d

2.4 事务

# 原子 CAS:如果 /lock 不存在则写入
etcdctl txn <;<EOF
compares:
  create("/lock/my-resource") = "0"

success requests (get, put, del):
  put /lock/my-resource "holder-abc"

failure requests (get, put, del):
  get /lock/my-resource
EOF

第三章:etcd vs Redis vs ZooKeeper vs Consul

特性 etcd Redis ZooKeeper Consul
CAP CP AP CP CP
共识算法 Raft 无(主从) ZAB Raft
配置存储 ✅ KV ✅ KV ✅ 树形 ✅ KV
Watch ✅ Pub/Sub
Lease/TTL ✅ EXPIRE ✅ Ephemeral
事务 ✅ MULTI/EXEC ✅ Multi
K8s 原生 ✅(核心依赖)
多数据中心
侧重点 一致性 + 简洁 性能 + 丰富数据结构 配置 + 选举 服务发现 + Mesh

第四章:生产运维要点

4.1 数据压缩与碎片整理

# 查看当前 revision
etcdctl endpoint status --write-out=table

# 压缩旧版本(保留最近 1000 个)
rev=$(etcdctl endpoint status --write-out=json | jq '.[0].Status.header.revision')
etcdctl compact $(($rev - 1000))

# 碎片整理
etcdctl defrag --cluster

4.2 备份与恢复

# 备份
etcdctl snapshot save backup.db

# 恢复
etcdctl snapshot restore backup.db \
  --data-dir=/var/lib/etcd-new \
  --name=infra0 \
  --initial-cluster=infra0=http://10.0.0.1:2380 \
  --initial-advertise-peer-urls=http://10.0.0.1:2380

4.3 安全加固

# 启用认证
etcdctl user add root
etcdctl auth enable

# 创建角色和用户
etcdctl role add app-role
etcdctl role grant-permission app-role readwrite /config/app/ --prefix
etcdctl user add app-user
etcdctl user grant-role app-user app-role

思考题

  1. 为什么 etcd 推荐奇数节点(3/5/7)?4 节点和 3 节点的容错能力一样吗?
  2. Raft 的 Leader 选举中如果出现"脑裂"(两个 Leader),etcd 怎么处理?客户端怎么知道谁是真正的 Leader?
  3. etcd 的 MVCC 机制和数据库的 MVCC 有什么异同?为什么要保存历史版本?
  4. Kubernetes 中所有资源都存储在 etcd 中,etcd 挂了对 K8s 集群有什么影响?已有 Pod 还能继续运行吗?

下一步

  • 学习 etcd + gRPC 实现命名解析(Name Resolver)
  • 学习 Kubernetes CRD + etcd 原理
  • 学习 etcd 性能调优:磁盘/网络/配置参数

信息

路径
/tech-stacks/etcd/tutorial/etcd 分布式一致性存储入门.md
更新时间
2026/5/31