Etcd,真的需要集群部署吗?

发布于:2025-08-07 ⋅ 阅读:(29) ⋅ 点赞:(0)

Etcd是Kubernetes中一个非常重要的组件,它存储整个集群的元数据,维持着集群的稳定。在生产环境中,一般奇数个节点部署,用的最多的是三个或五个节点。三个节点的情况下,可以容忍一个节点故障,五个节点的集群可以容忍两个节点的故障。实际情况可能并不如理想的完美。在深入讨论这个问题之前,有必要介绍etcd下的工作原理:

etcd集群中的节点有三类角色:

  • Leader(领导者):

唯一处理写请求的节点(读请求默认也从 Leader 读取,保证强一致性);负责将写操作转换为“日志条目”,并同步给所有 Follower;维护集群的心跳(定期向 Follower 发送消息,证明自己存活)。

  • Follower(追随者):

被动接收 Leader 的日志同步和心跳;若超时未收到 Leader 心跳,则转为 Candidate 发起选举。

  • Candidate(候选人):

当 Follower 检测到 Leader 故障时,主动发起 Leader 选举的临时角色;向其他节点请求投票,获得多数派(≥N/2+1)投票后便成为新 Leader。

Leader角色在etcd集群中,有着举足轻重的作用,整个客户端的读写请求都由它一个来处理。在一个繁忙的Kubernetes中,充当leader角色的节点负载会比较大,这就是为什么etcd对服务器的硬盘、CPU、内存的要求比较高。我曾经遇到过因为服务器硬盘IO过低(100MB/s左右),导致整个etcd集群功能异常。

在Leader节点出问题后,新Leader节点的选举是一个耗时的过程。

每个 Follower 维护一个随机超时时间(默认 150-300ms),若超时未收到 Leader 心跳,则认为 Leader 故障,转为 Candidate。Candidate 向所有节点发送 RequestVote 请求,节点会投票给第一个满足以下条件的 Candidate:

1)Candidate 的日志比自己“新”(日志索引更大,或索引相同但任期更大)
2)未在本轮选举中投票给其他 Candidate。

Candidate 获得超过半数节点的投票后,立即成为新 Leader,并向所有节点发送心跳,阻止其他节点发起新选举。

在分布式系统设计中,不可避免会涉及CAP问题。etcd是一个满足CP的分布式系统,也就是它能同时提供数据一致性和容忍集群分区。容忍集群分区,通过上面介绍的多数节点投票机制实现。以三个节点为例,当Leader节点和其余两个节点出现网络不通的情况时,因为原本非Leader角色的两个节点可以通信,它们很快就会选出一个新的Leader对外提供服务,而原来的Leader节点因为不能达到法定票数(得票>=2),则停止服务。

为了满足数据的一致性,etcd集群也做了很大牺牲,在实际生产环境中,虽然我们部署了三个节点,但真正干活就Leader节点,其他两个节点只是存储数据的备份。

etcd使用WAL和快照来实现数据的持久化,客户的写入数据会先记录在Leader节点的WAL日志中,然后这些日志会同步给Follower节点,Leader节点在收到多数Follower节点的正确回复后,会持久化这次写入的数据。快照是WAL日志的辅助,如果数据量不大的话,完全可以不用快照,但生产环境下,WAL日志大概率会增加的飞快,如果没有快照,节点恢复将变得非常慢。有了快照,快照前生成的WAL文件就可以安全的删除,这个机制和PostgreSQL类似。

下面是一个实际的写请求处理步骤(假设集群是三个节点):

  1. 客户端向任意节点发送写请求(如 PUT /key value);
  2. 若接收节点是 Follower,会转发请求到 Leader;
  3. Leader 将写操作封装为“日志条目”(包含操作内容、任期号、索引),写入本地 WAL(Write-Ahead Log,预写日志);
  4. Leader 向所有 Follower 发送 AppendEntries 请求(携带日志条目);
  5. Follower 收到日志后,先写入本地 WAL,再返回确认(ACK);
  6. 当 Leader 收到多数 Follower 的 ACK(3 节点需 2 个确认,含 Leader 自己),则标记该日志为“已提交”(Committed);
  7. Leader 将日志条目应用到状态机(即更新内存中的键值对),并返回“成功”给客户端;
  8. 后续心跳中,Leader 会通知 Follower 提交已确认的日志,Follower 也将日志应用到状态机。

实话说,分布式系统真的是一个非常复杂的系统,部署三节点或五节点的etcd集群,但如果网络很脆弱,比如这些节点都接入一台交换机,那么一次不完美的网络维护就可能导致整个集群挂掉。如果我们的集群很小,本身网络没有冗余,服务器也没有双电源,那么单节点的etcd用起来会更省心,只要定期将快照异机备份就好,因为即使运行etcd节点的服务器出问题了,只要没有新的调度任务,整个集群中已经运行的Pod还是会正常运行的,而且你会发现etcd处理读写的速度明显比集群情况下更快。

当然,实际操作时,还是看集群本身规模和重要性,如果你的集群是公共的且对外提供服务,那怎么保护都不为过。





 


网站公告

今日签到

点亮在社区的每一天
去签到