
文章插图
【分布式系统如何保证一致性】3. 选举流程要点总结
「1」Leader 角色通过发送心跳报文来维护自己的统治地位 。「2」Follower 角色接收不到心跳报文,则超时开始下一轮的选举 。「3」每个节点的超时时间都是随机的 。「4」成为 Leader 节点需要赞同票超过半数 。「5」选举结束,所有除 Leader 的候选人又变回 Follower 服从 Leader 。
日志同步
当选举完成后,客户端进行的操作都要通过 Leader 来进行 。Leader 接受到客户端发来的操作请求后,首先记录到日志中,此时为 uncommitted 状态 。然后在下一个心跳报文中通知所有 Follower,当大多数 Follower 响应 ACK 后,Leader 响应客户端,进入 committed 阶段,并向 Follower 发送 commit 通知应用( Apply )操作 。
日志同步流程如下:

文章插图
上图中的序号对应一个存储的步骤, 日志同步 流程总结如下:「1」client 给 Leader 发送一个操作请求,假设为 SET X=8 。「2」Leader 会把 SET X=8 这个操作记录到本地 log,此时为 uncommited 状态,同时将这个操作发送给所有的 Follower 。「3」Follower 接收到操作请求后,也将 SET X=8 这个操作记录到本地 log(uncommited 状态),然后给 Leader 回复 ACK 信息 。「4」Leader 节点当接收到的 ACK 超过半数后,给 client 回复 ACK 信息,进入 commited 阶段 。「5」Leader 节点首先应用自己的 log,然后将 commit 消息发送给 Follower, 让 Follower 也 应用自己存储的日志信息 。

文章插图
Raft 中的异常处理
我们已经介绍了 Raft 算法的正常处理流程,然而现实总是很骨感,会出现各种异常的情况 。client 和 Leader 之间的通信异常,不会影响到集群内部状态的一致性,不再赘述;如果在一个任期内,Follower 角色宕机,处理流程比较简单 。其呈现出来的现象就是 步骤「3」异常,然而只要 Leader 能够接收到超过半数的 ACK,就不会影响到正常的存储流程 。但是 Leader 角色会针对该 Follower 节点,持续进行步骤 「2」 的动作,直到接收到步骤 「3」的回应信息或者我们把该 Follower 节点从集群中拿掉;Raft 协议强依赖 Leader 节点的可用性来确保集群数据的一致性 。下面重点介绍在各种情况下 Leader 节点出现故障时,Raft 协议是如何保障数据一致性的 。
1. 写操作 到达 Leader 节点,但尚未同步到 Follower 节点
此刻集群的状态如下,用方框中的灰色表示当前处于 uncommited 状态 。

文章插图
如果集群在此状态,Leader 节点宕机,则 Raft 的处理流程如下:「1」Follower 节点超时,然后选举出新一任期的 Leader,然后它并没有处于 uncommited 状态的日志 。「2」Client 节点由于 Ack 超时,可安全发起重试 。「3」原来的 Leader 节点恢复后以 Follower 角色重新加入集群 。并从当前任期的新 Leader 处同步数据,可能会覆盖原来处于 uncommited 状态的日志 。
2. 写操作 到达 Leader 节点,且将写操作同步到 Follower 节点,但还未向 Leader 回复 ACK 信息 。
此刻集群的状态如下,用方框中的灰色表示当前处于 uncommited 状态 。

文章插图
如果集群在此状态,Leader 节点宕机,则 Raft 的处理流程如下:「1」Follower 节点超时,然后选举出新一任期的 Leader,并且它存在处于 uncommited 状态的日志 。「2」新的 Leader 节点假装没有刚才的选举过程,继续从步骤(2)开始执行,以完成数据的提交 。「3」Client 节点由于 ACK 超时,可安全发起重试 。「4」原来的 Leader 节点恢复后以 Follower 角色重新加入集群 。并从当前任期的新 Leader 处同步数据 。
此时,在上面步骤「1」中选举新的 Leader 节点时,需要满足一个限制条件,即新的 Leader 节点需要具有最新的日志信息,所谓的最新是通过任期和日志的偏移量两个参数来判定的,这个限制是为了解决只有部分 Follower 节点接收到写操作请求的情况 。
3. Leader 节点接收到写操作的 ACK 信息,处于 commited 状态,然而 Follower 处于 uncommited 状态 。
此种情况是由于,在步骤(5)执行过程中,Leader 宕机导致的,此刻集群的状态如下,用方框中的灰色表示当前处于 uncommited 状态,用方框中的黑色表示当前处于 commited 状态,同时圆圈中的值表示操作已经生效 。
推荐阅读
- 系统管理员入门:排除故障
- Linux系统 tcpdump 抓包命令使用教程
- 产后如何控制体重,推荐四个减肥方法
- 如何对抗衰老,日常做好四件事
- 快手小店怎么找到对应主营类目,如何设置? 快手小店怎么设置商品分类
- sk2的效果 日本的sk2其实效果如何
- 如何在淘宝直播加人 淘宝直播怎样加好友
- 浙江省|上班族如何充实自己,你找对方法了吗?
- 加拿大|加拿大移民详解:如何通过找工作的方式拿到枫叶卡?
- 如何补气血又不上火
