Raft协议
大约 6 分钟
RAFT动画解说
http://thesecretlivesofdata.com/raft/
- 是一种复制状态机,是一种能让分布式系统中各个节点达成共识的一套框架协议或者算法
- 主要有两个过程
- leader选举过程
- 日志复制过程
- 一个共三种角色,leader/follower/candidate
- 满足的是CAP中的CP,和zk一样,zk也是CP,也是在leader选举过程中不可用
leader选举过程
1. 最开始各个节点均已follower角色启动,并各自机出一个超时时间,这个超时时间称之为 election timeout. 一般在150ms-300ms之间
2. 如果节点超过这个时间未收到leader的心跳信息,则发起一轮leader的选举,并且自己的角色转换为candidate,假设a节点发起了一轮选举
3. a节点首先给自己投一票,然后向其他节点发起投票请求(vote request),
4. 其他节点收到投票请求后,如果自己在这轮投票中尚未投票(注意是本轮,有个term变量来记录轮次),则进行投票(谁要求投票,则投给谁)
5. 如果a节点收到过半节点的投票,则自己成为leader,并开始向其他节点发送日志和心跳
注意:第5点要过半的投票,是大于一半,不是大于等于,这个很关键,过半可以防止多个leader同时对外提供服务,但仍有可能出现多个leader,但只有一个leader可用
由于在leader的选举过程中,要求必须有过半节点的投票才能成为leader,所以在同一轮投票中最多产生一个leader,但并不一定能产生leader(后面会说到)
注意:这里说的是同一轮投票中,也就是说某个时刻可能会有两个leader,甚至更多leader,但他们不是同一轮选举产生
但只有一个leader才能完成客户端请求,这种情况一般发生在网络分区环境中,后面会说到
同一轮选举中不能产生leader的情况: 比如现在又4个节点A/B/C/D,A,B两个节点的election timeout一样,
两个节点同时发起了选举(他们的term是一样的,所以是同一轮选举),这个时候C/D两个节点分别同时收到两个 投票请求,分别来源于A/B两个节点,
那么有可能c投给了a,d投给了b,那么a/b两个节点收到的投票都是2(包括自己的一票),都没有过半,所以这轮选举未产生leader.
这种情况就是需要再次发起新一轮投票(一般可以再次随机自己的election timeout来达到目的)
某个时刻,集群中有两个或更多leader的情况: 比如此时有A/B/C/D/E五个节点,a是leader。
此时发生了网络分区,A/B两个节点一个分区,C/D/E三个节点一个分区。这个时候发往leader A的请求,由于没有过半节点的日志复制成功,
所以不能完成客户端的情况。同时C/D/E三个节点由于网络分区,无法收到A的心跳信息,
最终C/D/E三个节点会触发election timeout并选举产生一个leader,假设是C.(因为数量过半嘛)
那么此时这个集群就会有两个leader。但只有一个leader能完成客户端请求。
如果某个时候,网络分区消除了,会发生什么事呢?
先看C/D/E三个节点,这三个节点有可能收到A节点的心跳或者日志复制信息,但会发现A节点已经不是最新的leader(应该是通过term判断),
所以不会做出正确的响应,所以之前提交到a的请求 即使在网络分区消除后也不能成功。
再看A节点,当他收到C的心跳和日志复制信息,发现自己已经不是最新的leader了,于是把本地未提交的log进行回滚,并转换follower,同步leader C的日志
再看b节点,基本过程和a的相似,最终跟随C节点
日志复制过程
1. 比如客户端发送一个 set 5的请求给leader,
2. leader收到请求后,先追加到自己的日志文件中(WAL,mysql的redo log也是WAL),此时日志处于uncommited状态
3. 然后通过心跳包把这个set 5传递给follower,
4. follower收到这个心跳后,也把日志追加到自己的日志文件中,并返回一个正常的响应给leader
5. 当leader收到过半节点的正常响应后,日志状态改为commited状态,同时执行set 5的动作,然后返回一个正确的响应给客户端
- WAL: 什么叫WAL,全称Write Ahead Log,也就是同一个事务的数据,日志的数据必须先于最终的数据落盘
系统推荐
- MAT工具
- getPath vs getAbsolutePath vs getCanonicalPath
- Git合并多个提交并push到远程仓库
- ES6.2.3(3节点)数据迁移到ES7.4.1(5节点)
- PGSQL GIN索引“失效”
- 线上FullGC频繁的排查
- linux_no_space_left_on_device
- InnoDB存储引擎
- CountDownLatch源码解读
- RocketMQ
- GitHub Workflow突然报错
- 表单重复提交解决方案
- 随机毒鸡汤:最好别收拾房间,当房间收拾干净时,你就是房间里唯一的垃圾。