《云计算技术系列丛书 云原生分布式存储基石: etcd深入解析》—1.4.3异常情况
1.4.3 异常情况
一个Raft系统的异常情况通常可以分为两大类:领导人异常和追随者/候选人异常。
追随者和候选人异常问题的解决方法要比领导人异常简单得多。如果一个追随者或者候选人崩溃了,那么领导人在这之后发送给他们的RequestVote RPC和AppendEntries RPC就会失败。Raft算法通过领导人无限的重试来应对这些失败,直到故障的节点重启并处理了这些RPC为止。如果一个节点在收到RPC之后但在响应之前就崩溃了,那么它会在重启之后再次收到同一个RPC。因为Raft算法中的RPC都是幂等的,因此不会有什么问题。例如,如果一个追随者收到了一个已经包含在其日志中的 AppendEntries RPC,那么它会忽略本次请求。
由于Raft算法是强领导人特性的,因此保证领导人即使出现故障也不影响数据一致性就显得格外重要。下面先来看下数据提交的全过程,如图1-13所示。
图1-13 Raft算法数据交换示意图
图1-13中,数据的流向只能从Leader节点(L)向Follower节点(F)转移。当Client向集群Leader节点提交数据时,Leader节点接收到的数据处于未提交状态(Uncommitted),接着Leader节点会并发向所有Follower节点复制数据并等待接收响应,在确保集群中至少有超过半数的节点已经接收到数据之后,再向Client确认数据已接收。一旦Leader节点向Client发出数据接收ACK响应之后,即表明此时数据状态进入已提交(Committed)状态,Leader节点会再次向Follower节点发送通知,告知该数据状态已提交。
在这个过程中,领导人可能会在任意阶段崩溃,下面将逐一示范Raft算法在各个场景下是如何保障数据一致性的。
(1)数据到达Leader前
如图1-14所示的是数据到达Leader前领导人出现故障的情形。
图1-14 数据到达Leader之前
这个阶段领导人出现故障不会影响数据一致性,因此此处不再赘述。
(2)数据到达Leader节点,但未复制到Follower节点
如图1-15所示的是数据到达Leader节点,但未复制到Follower节点时,领导人出现故障的情形。
图1-15 数据到达Leader节点,但未复制到Follower节点
如果在这个阶段Leader出现故障,此时数据属于未提交状态,那么Client不会收到ACK,而是会认为超时失败可安全发起重试。Follower节点上没有该数据,重新选主后Client重试重新提交可成功。原来的Leader节点恢复之后将作为Follower加入集群,重新从当前任期的新Leader处同步数据,与Leader数据强制保持一致。
(3)数据到达Leader节点,成功复制到Follower的部分节点上,但还未向Leader响应接收
如图1-16所示的是数据到达Leader节点,成功复制到Follower的部分节点上,但还未向Leader响应接收的情形。
图1-16 数据到达Leader节点,成功复制到Follower部分节点,但还未向Leader响应接收
如果在这个阶段Leader出现故障,此时数据在Follower节点处于未提交状态(Uncommitted)且不一致,那么Raft协议要求投票只能投给拥有最新数据的节点。所以拥有最新数据的节点会被选为Leader,再将数据强制同步到Follower,数据不会丢失并且能够保证最终一致。
(4)数据到达Leader节点,成功复制到Follower的所有节点上,但还未向Leader响应接收
这种情形如图1-17所示。
图1-17 数据到达Leader节点,成功复制到Follower所有节点,但还未向Leader响应接收
如果在这个阶段Leader出现故障,虽然此时数据在Follower节点处于未提交状态(Uncommitted),但也能保持一致,那么重新选出Leader后即可完成数据提交,由于此时客户端不知到底有没有提交成功,因此可重试提交。针对这种情况,Raft要求RPC请求实现幂等性,也就是要实现内部去重机制。
(5)数据到达Leader节点,成功复制到Follower的所有或大多数节点上,数据在Leader上处于已提交状态,但在Follower上处于未提交状态
这种情形如图1-18所示。
图1-18 数据到达Leader节点,成功复制到Follower所有或多数节点,数据在Leader上处于已提交状态,但在Follower处于未提交状态
如果在这个阶段Leader出现故障,那么重新选出新Leader后的处理流程与阶段3一样。
(6)数据到达Leader节点,成功复制到Follower的所有或大多数节点上,数据在所有节点都处于已提交状态,但还未响应Client
这种情形如图1-19所示。
图1-19 数据到达Leader节点,成功复制到Follower所有或多数节点,数据在所有节点都处于已提交状态,但还未响应Client
如果在这个阶段Leader出现故障,此时集群内部数据其实已经是一致的,那么Client重复重试基于幂等策略对一致性无影响。
(7)网络分区导致的脑裂情况,出现双Leader
网络分区将原先的Leader节点和Follower节点分隔开,Follower收不到Leader的心跳将发起选举产生新的Leader。这时就产生了双Leader,原先的Leader独自在一个区,向它提交数据不可能复制到大多数节点上,所以永远都是提交不成功。向新的Leader提交数据可以提交成功,网络恢复后旧的Leader发现集群中有更新任期(Term)的新Leader,则自动降级为Follower并从新Leader处同步数据达成集群数据一致。具体情形如图1-20所示。
图1-20 网络分区导致的脑裂情况,出现双Leader
以上7种场景穷举了一个3节点的最小集群面临的所有异常情况,可以看出Raft算法在各种异常场景下均能保证数据的一致性。
- 点赞
- 收藏
- 关注作者
评论(0)