etcd 学习系列(二):集群架构 —— 3 节点是如何工作的

前言

上一篇文章我们知道了 etcd 是一个分布式的 key-value 存储。但"分布式"具体是怎么实现的?3 台机器组成一个集群,它们之间是怎么分工合作的?

这篇文章,我们来拆解 etcd 集群的架构。


一、3 个节点,3 种角色

在 etcd 集群中,每个节点在任意时刻都处于以下三种角色之一:

角色 职责 数量
Leader(领导者) 处理所有写请求,定期发心跳给 follower 1 个
Follower(追随者) 被动同步 leader 的数据,处理读请求 2 个
Candidate(候选者) 选举期间的临时角色 0 或 多个
复制代码
┌──────────────┐       ┌──────────────┐       ┌──────────────┐
│   Leader     │       │   Follower   │       │   Follower   │
│   (主)      │←───→│   (从)      │←───→│   (从)      │
│   处理写请求  │       │   同步数据    │       │   同步数据    │
│   发心跳      │       │   处理读请求  │       │   处理读请求  │
└──────────────┘       └──────────────┘       └──────────────┘

查看集群成员

bash 复制代码
etcdctl member list

输出示例:

复制代码
member xxxx: name=node-1 peerURLs=http://10.0.0.1:2380 clientURLs=http://10.0.0.1:2379 isLeader=false
member yyyy: name=node-2 peerURLs=http://10.0.0.2:2380 clientURLs=http://10.0.0.2:2379 isLeader=true
member zzzz: name=node-3 peerURLs=http://10.0.0.3:2380 clientURLs=http://10.0.0.3:2379 isLeader=false

isLeader 字段可以知道谁是当前的 leader。


二、两个端口:2379 和 2380

etcd 集群使用两个端口通信:

端口 用途 类比
2379 Client 端口,给应用(客户端)用的 前台接待
2380 Peer 端口,etcd 节点之间通信用的 员工通道
复制代码
       应用(你的服务)
           │
           │ 2379(客户端连接)
           ▼
┌──────────────────────────────┐
│  etcd 集群                    │
│                              │
│  ┌──────┐  2380  ┌──────┐   │
│  │节点 A │←──────→│节点 B │   │
│  └──────┘         └──────┘   │
│      ↑               ↑       │
│      │ 2380          │ 2380  │
│      ↓               ↓       │
│  ┌──────┐                   │
│  │节点 C │                   │
│  └──────┘                   │
└──────────────────────────────┘

关键理解:节点之间不需要 2379

etcd 节点之间通过 2380 同步数据、选举 leader。不需要互开 2379,因为 2379 是给客户端用的。

复制代码
etcd 节点之间:
  ├── 2380 → ✅ 必须互开,用于数据同步、选举 leader
  └── 2379 → ❌ 不需要互开,这是给客户端用的

三、防火墙策略实践

在实际部署时,建议用 firewalld 或 iptables 限制端口访问:

bash 复制代码
# 允许 etcd 节点之间 2380 通信
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="10.0.0.1" port protocol="tcp" port="2380" accept'
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="10.0.0.2" port protocol="tcp" port="2380" accept'
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="10.0.0.3" port protocol="tcp" port="2380" accept'

# 允许应用访问 2379
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.1.100" port protocol="tcp" port="2379" accept'

firewall-cmd --reload

四、写请求的完整流程

当应用要修改一个配置值时,完整的流程是这样的:

复制代码
1. 应用发请求到任意节点(比如节点 A)
2. 如果节点 A 不是 leader:
   → 节点 A 把请求转发给 leader(通过 2380 或 2379,取决于客户端版本)
3. leader 收到请求:
   a. 写入自己的 WAL 日志
   b. 并行发给所有 follower
4. follower 收到 → 写入自己的 WAL → 回复 leader "收到"
5. leader 收到过半确认(自己 + 至少 1 个 follower)→ 返回成功
6. 应用收到 "修改成功"

为什么需要"过半确认"?

复制代码
3 节点集群,quorum = 2

如果 leader 写入成功就返回,不等待 follower:
  → leader 突然宕机
  → 数据还没同步到其他节点
  → 数据丢了 ❌

如果 leader 等待过半确认:
  → leader 写入 → 同步到至少 1 个 follower → 返回成功
  → leader 宕机 → 另一个 follower 有数据 → 当选新 leader
  → 数据不丢 ✅

五、读请求:线性读 vs 串行读

etcd 支持两种读模式:

线性读(Linearizable Read)

复制代码
客户端 → 读请求 → follower → 转发给 leader
leader 确认自己还是 leader → 返回最新数据

特点:保证读到最新数据,但多了一次网络转发

串行读(Serializable Read)

复制代码
客户端 → 读请求 → 任意节点 → 直接返回自己内存中的数据

特点:性能好,但可能读到毫秒级延迟的旧数据

用哪个取决于客户端 API 版本

客户端 API 默认读模式 说明
etcd v2 API 串行读 v2 不支持线性读,固定串行
etcd v3 API 线性读 默认线性读,可改为串行读

六、查看集群状态

bash 复制代码
# 集群健康
etcdctl cluster-health

# 成员列表
etcdctl member list

# 详细状态(v3 API)
export ETCDCTL_API=3
etcdctl --endpoints=http://127.0.0.1:2379 endpoint status --write-out=table

输出示例:

复制代码
+------------------+------------------+---------+---------+-----------+-----------+------------+
|    ENDPOINT      |        ID        | VERSION | DB SIZE | IS LEADER | RAFT TERM | RAFT INDEX |
+------------------+------------------+---------+---------+-----------+-----------+------------+
| 127.0.0.1:2379   | ad245981f2b01e41 |  3.3.11  |  123 MB |    false  |    12345  |   67890    |
+------------------+------------------+---------+---------+-----------+-----------+------------+
字段 含义
VERSION etcd 二进制版本
DB SIZE 数据文件大小
IS LEADER 是否 leader
RAFT TERM 第几次选举周期
RAFT INDEX 已经处理了多少条写操作

小结

etcd 集群的核心就是:3 个节点,1 个 leader,2 个 follower,2380 同步数据,2379 服务客户端

  • 写操作必须经过 leader,需要过半确认
  • 读操作取决于 API 版本(v2 串行,v3 线性)
  • 防火墙策略:2380 节点间互开,2379 只对客户端开放

下一篇文章,我们来深入 Raft 协议------分布式一致性的核心算法。


上一篇:[etcd 学习系列(一):从业务需求出发,理解 etcd 是什么](#etcd 学习系列(一):从业务需求出发,理解 etcd 是什么)

下一篇:[etcd 学习系列(三):Raft 协议 ------ 分布式一致性就是这么简单](#etcd 学习系列(三):Raft 协议 —— 分布式一致性就是这么简单)

相关推荐
Dawson Zhu1 小时前
从单体到联邦:多Agent架构的必要性与设计哲学
人工智能·语言模型·架构·aigc·agi
千里马-horse1 小时前
第 60 章 模拟器架构
架构·aosp
水巷石子2 小时前
备考系统架构设计师第一天
学习·架构·软考·设计·考试
pt10432 小时前
网络自动化Python课程:Cisco PyATS网络自动化测试框架
运维·自动化
武子康2 小时前
商业比较词进入 AI Overview:Semrush 60 万关键词研究能说明什么
人工智能·ai·架构·agent·claude·codex·semrush
m0_587383003 小时前
全民健身解决方案软件开发实战:从架构设计到落地指南
java·spring boot·spring·架构·需求分析
小袁拒绝摆烂3 小时前
Jenkins部署经验
运维·jenkins
刚入门的大一新生3 小时前
Linux-进程控制
linux·运维·服务器·c++
上火的金鱼妹3 小时前
K8S基础组件作用和关系整理
linux·运维·服务器·kubernetes