Raft论文阅读笔记
发表时间 2019-10-16  |  浏览量:  |  分类: Raft

问题1

  1. 目前已经有一个正常的Leader节点A,任期号为1
  2. 由于丢包或网络波动等可能的原因,节点X心跳超时
  3. 节点X自增当前任期号,自增后节点X的当前任期号为2,并转为候选人
  4. 此时节点X的网络恢复正常
  5. 节点X向集群中其他节点发送RequestVote RPC

:

  1. 此时其他Follower节点如何响应节点XRequestVote RPC
  2. 此时Leader节点A如何响应节点XRequestVote RPC

个人见解:如果在节点X发起选举请求的过程中,Leader和其他Follower都没有收到来自客户端的写操作,那么所有节点都承认节点X的选举,Leader节点A自动退化为Follower。如果在这个选举期间有新的日志条目成功提交,那么自然大多数节点都会拒绝节点X的请求,因为它不持有最新的数据。

论文中有以下这段话与个人见解冲突 :
when they believe a current leader exists. Specifically, if a server receives a RequestVote RPC within the minimum election timeout of hearing from a current leader, it does not update its term or grant its vote.
each server waits at least a minimum election timeout before starting an election.
if a leader is able to get heartbeats to its cluster, then it will not be deposed by larger term numbers
因此,像问题中描述的情况,除了节点X外,其他的节点依然是有收到节点A的心跳的,会忽略节点X的投票请求。

问题2

心跳超时的节点是否在恢复或者完成选举之前都拒绝提供服务?

个人见解:是,心跳超时,就无法保证自己的数据是最新的了。

问题3

所有请求最终都是由Leader处理,Leader压力太大?优化空间?

问题4

是否一条日志从Leader复制到Follower后,Leader和Follower都不会更新commitIndex,而是仅仅存储这条日志,等到Leader收到大多数节点的ACK后,再通知Follower更新commitIndex

个人见解:不是,一旦从Leader复制到Follower,对于Follower来说这条日志就是已提交,但是此时作为Follower不会将这条日志应用到复制状态机中。Leader收到大多数节点的ACK后,Leader就提交对应的日志并应用到复制状态机,在下一次心跳,Follower就能知道刚刚的日志可以安全的应用到复制状态机中了(由注意点1得出的结论)。

问题5

5.4.3 安全性论证中的图9,有没有可能S3投票给S5后,S1又发送了提交日志的请求,此时S1S2收到提交日志请求,但是S5又成为新的Leader,S5丢失了数据。

个人见解:这个问题不存在,因为根本没有一个请求叫做提交日志,Raft中只有两种RPC(在5.4节之前),Follower收到AppendEntries RPC后,就会将日志持久化并认为这些日志是已提交的(此时未应用到状态机中),因此对于Follower来说,不存在已持久化但未提交的日志。对于Leader,只有大多数节点都持久化成功,自己才会将日志持久化并提交,然后应用到状态机中,在下一个心跳中,Follower就可以知道哪些已提交的日志是可以安全应用到状态机中了。

问题6

Leader发送的心跳收不到响应怎么办?比如Leader的网络出问题了?或者只收到了部分(大于一半或者小于等于一半 )节点的响应。

注意点

注意点1:之前任期的日志

当前任期的Leader不能直接提交之前任期的日志,必须要等到当前任期有日志符合提交条件了,再顺便一起将之前任期的日志进行提交。

图片描述

如上图,(c)中是不允许S1直接将任期2的日志复制给S3并进行提交的,否则就会出现(d)中S5覆盖已提交日志的问题。S1必须像(e)中一样,在提交任期4的日志时,顺便把任期2的日志给提交了。

注意点2:committed

committed是一个概念性词语,实际上对于Follower来说,成功持久化一条日志就代表着这条日志已被提交。
一旦一条日志被大多数节点持久化成功,那么这条日志就会被当前任期或者之后某一任期的Leader提交。因为不含有这条日志的节点,是无法获得大多数节点的投票成为Leader的(日志不够新)。
图6An entry is considered committed if it is safe for that entry to be applied to state machines

5.3节: The leader keeps track of the highest index it knows to be committed, and it includes that index in future AppendEntries RPCs (including heartbeats) so that the other servers eventually find out. Once a follower learns that a log entry is committed, it applies the entry to its local state machine (in log order)

注意点3:时间要求

广播时间(broadcastTime) << 选举超时时间(electionTimeout) << 平均故障间隔时间(MTBF)
比如:广播时间20ms,选举超时时间200ms,平均故障时间则为几小时甚至几天几个月

注意点4:客户端同一请求多次应用

客户端有可能会对同一个操作发送多次请求到raft集群中,为了保证幂等性,客户端发送的每一个不同的操作都需要有一个唯一序列号和客户端id,并且唯一序列号是顺序递增的,因此raft集群就能知道这个操作是否已经被提交并应用到状态集中,从而避免操作重放问题。

关闭

分类

Linux JavaScript Raft Java Git iptables 内网穿透 RocketMQ 算法 Go Hystrix

标签

Linux bond JavaScript Vue Raft 分布式 笔记 Java 字符串拆分 Git Socks5 iptables zerotier 内网穿透 网络 RocketMQ Docker 字符串 VPS VPN 算法 kmp Go json 日志 log4j slf4j 面试 后端开发 系统界面 翻译 Feign Spring Cloud Hystrix