【Java高级工程师蜕变之路】059 分布式一致性协议之Raft协议
Raft协议
什么是Raft协议
Paxos论证了一致性协议的可行性,但是不好懂,缺少必要的细节,工程实现难度高。广为人知的实现目前只zk的zab协议。
Paxos的出现为分布式的强一致性提供了很好的理论基础,但是paxos协议本身理解起来困难,实现复杂。
斯坦福大学的RamCloud项目中提出了易理解、易实现的分布式一致性复制协议Raft。C++、Java和Go都有对应的实现,Raft相对简洁。
引入主节点、通过竞选确认主节点。节点;类型:follower、candidate和leader。
leader会周期性的发送心跳包给follower。每个follower设置一个随机的竞选超时时间,一般为150~300ms,如果在这个时间内没有收到心跳包,就会变成candidate。进入竞选阶段,通过竞选阶段投票人多的成为leader。
Raft相关概念
- 节点状态
- Leader(主节点):接收client请求,写入本地后,同步到其他副本中
- Follower(从节点):从Leader中接收更新请求,然后写入本地日志文件。对客户端提供读请求
- Candidate(候选节点):如果Follower在一段时间内,没有接收到心跳,则判断Leader可能发生故障,发起主提议。节点状态从Follower变成Candidate状态,直到选主结束
- termId:任期号,时间被划分为一个个任期,每次选举后产生一个新的termId,一个任期内只能有一个leader。
- requestVote:请求投票,Candidate在选举过程中发起,收到多数派响应后成为leader。
竞选阶段流程
http://thesecretlivesofdata.com/raft/
单节点不存在数据一致性问题,一个节点容易达成一致性。
多个节点达成一致性
不同的状态
竞选流程
-
最初阶段,只有Folllower,没有leader
FollowerA等待随机竞选超时之后,没收到leader发来的心跳包,进入竞选阶段。
-
此时A发送投票请求给其他节点
-
其他节点会对请求进行回复,如果超过一般节点进行了回复,那么该节点就会由candidate变成leader
-
之后leader会周期性的给follower发送心跳包,follower接收到心跳包,会重新开始计时
leader节点宕机
多个Candidate竞选
- 如果有多个follower成为candidate,并且获得的票数相同,那么就需要重新进行投票。
-
当重新开始投票时,由于每个节点设置的随机竞选超时时间不同,因此再次出现多个candidate进行竞选并且获得相同票数的概率很低。
日志复制
-
来自客户端的修改都会传到leader。该修改还未提交,只是存在日志中
-
leader把修改复制到所有follower
-
leader会等待大多数follower都进行了修改,然后才将修改提交。
-
leader通知所有follower,让他们进行修改,此时所有节点达成一致。
-
多次日志复制的情况
网络分区
面对网络分区,Raft也可以保持一致。
-
初始状态下,B节点对其他节点发送心跳
-
当网络分区,出现网络分区的请求后,只能对A发送心跳,同时其他节点会再选出一个leader
网络分区情况的日志复制
网络分区数据复制也可以完成数据一致性
-
不同分区写入数据不同
-
最终E节点termid最大,成为leader节点,同步节点数据,达成数据一致性