Raft 协议学习笔记

1、什么是raft协议
维护分布式多副本数据一致性的协议。

什么是分布式一致性呢?举例说明:
如果一个系统只有一个节点,他作为DB Server,并存储了一个单独的值,然后他的client向他写入一个值,这时对于单节点,数据一致性很容易。
但是对于多个节点,怎样保证数据一致性呢?这就是分布式一致性问题。
raft就是实现了分布式一致性问题的协议。

下面看下raft协议怎样work的:
一个节点可能有3种状态:
1)follower
2)candidate
3)leader
所有节点的起始状态都是follower状态
如果follower的节点听不到leader的心跳,他会成为candidate状态,然后这个candidate发送投票请求给其他节点,其他节点会做投票,如果这个candidate获取的票数超过节点总数的一半,他就会成为leader。这个过程就是leader选举

有了leader后,这个分布式系统所有的changes都通过leader,每个change都会写入节点的log里,这时这个change的value属于uncommitted状态,然后leader复制这个日志给其他follower节点,然后leader等待这些follower的收到回复确认,如果超过半数收到,leader会commit这个value,并通知其他follower这个value已经committed了。这时,这个集群的数据就一致了。这个过程称为Log Replication

leader选举
在raft协议中,有2个超时设置来控制选举:
1)选举超时:一个follower等待leader心跳超时后,会成为Candidate,这个超时时间是随机的,在150ms ~ 300ms之间,当选举超时后,follower变成了candidate,并启动一轮新的选举,这个candidate会先给自己投票,然后再发送投票请求给其他节点,被请求投票的节点,如果还没有投票过,则会投票给这个candidate,然后reset他的选举超时时间。一旦某个candidate获得了超过节点总数半数的投票,就成为了leader。
2)心跳超时:然后这个leader会发送Append Entries消息给他的followers,这些被发送消息的间隔时间,被成为心跳超时(heartbeat timeout),这个过程会持续,直到一个follower收不到心跳消息,并成为一个candidate。然后停掉leader, 并开始一轮新的选举过程。

Log Replication
在选出Leader后,会复制所有的changes给其他follower,这个过程复用Append Entries消息相同的流程。
首先client给Leader发送一个changes请求,leader记录到log中,然后发送给其他follower在下一次心跳时,然后leader如果收到超过半数的follower的收到确认,则commit这个change, 并告知client发送成功。

关于raft协议在network partitions的脑裂时怎样保证数据一致性的?
假设有5个节点:A,B,C,D,E,由于网络故障,脑裂把A,B分成一边,C,D,E分成一边,这时两边会有两个leader,这时,两边的client会分别给这两边的系统发送change请求,一个请求发送change 3请求给B,这时,B不能做Log Replication超过半数,因为他只能和A通信,所以3无法commit;而另一边的客户端发送change 8请求给C,这个请求可以成功commit, 因为他超过了半数。
接下来,网络恢复了,看raft怎样修复脑裂带来的问题?
这时,B看到有了更高的选举,并下台。然后,A和B将回滚他们未commit的值3,并接收新leader的log replication,这样,数据就变得一致了。


一、前言

分布式存储系统通常通过维护多个副本来进行容错,提高系统的可用性。这就必须要解决分布式存储系统的最核心问题:维护多个副本的一致性。

1.1、什么是一致性

一致性(consensus),是构建具有容错性(fault-tolerant)的分布式系统的基础。在一个具有一致性性质的的集群里,同一时刻所有节点中的数据有相同的值。集群具有自动恢复的性质,当少数节点失效时,不会影响整个集群对外提供服务;但当超过一半节点失效时,整个集群不可用(但不会返回错误的结果)。

一致性协议就是用来干这事的,及用来保证在小部分副本宕机时,系统仍在可正常对外提供服务。

一致性协议基于replicated state machines,即所有节点都从一个state出发,都经过同样的一些操作序列(log),最后达到同样的state。

在这里插入图片描述
系统中每个节点有三个组件:

1、状态机:当我们说一致性时,就是在说要保证这个状态机的一致性。状态机 会从log里面取出所有的命令,然后执行一遍,得到的结果就是我们对外提供的保证了一致性的数据。

2、Log:保存了所有的修改记录

3、一致性模块:一致性模块算法就是用来保证写入的Log的命令的一致性,这也是raft算法的核心内容。

二、Raft 协议

2.1、Raft简介

Raft是一种更容易理解的一致性算法,意在取代Paxos算法。目前,各种主流语言中都有一些开源实现,如基于JGroup的Raft协议实现。

动画版Raft的原理:http://thesecretlivesofdata.com/raft/

2.2、Raft原理

在Raft中,每个节点会处于下面三种状态中的一种:

  • Follower:所有节点都以Follower状态开始,如果没有收到leader消息,则会从follower变成candidate。
  • Candidate:会向其他节点“拉选票”,如果得到大部分的选票,就会成为leader。这个过程就叫做Leader选举(Leader Election)
  • Leader:所有对系统的修改都会先经过Leader。每个修改都会写一条日志(Log Entry)。Leader收到修改请求后的过程如下,这个过程叫做日志复制(Log Replication):
    • 复制日志到所有Follower节点(replicate entry)
    • 大部分Follower响应时,才会提交日志
    • 通知所有Follower节点日志已提交
    • 所有Follower也提交日志
    • 现在整个系统处于一致性状态

2.2.1、Leader Election

当Follower在选举超时时间(election timeout)内未收到Leader的心跳消息(append entries),则变成candidate状态。为了避免选举冲突,这个超时时间是一个150~300ms之间的随机数。

成为candidate的节点发起新的选举期(election term)去“拉选票”:

  • 重置自己的计时器
  • 投自己一票
  • 发送Request Vote消息给其他Follower

如果接收节点follower在新term内没有投过票,他就会投给这个candidate,并重置自己的选举超时时间。candidate拉到超半数选票就会成为leader,并定时发送心跳 – Append Entries消息,去重置各个Follower的计时器。当前Term会继续指导某个Follower接收不到心跳并成为candidate。

如果不巧,两个Follower同时成为candidate都去“拉票”怎么办?这时会发生Split Vote情况。两个节点可能都拉到了同样多的选票,胜负难分,选举失败,本Term没有Leader。之后又有计时器超时的Follower会成为candidate,将开始新一轮的投票。

2.2.2、Log Replication

当发生改变时,Leader会复制日志给Follower节点,这也是通过Append Entries心跳消息完成的。前面已经列举过Log Replication的过程,这里就不重复了。

Raft能够正确地处理网络分区(“脑裂”)问题。假设A~E五个节点,B是Leader。如果发生“脑裂”,A、B成为一个子分区,C、D、E成为一个子分区。此时C、D、E会发生选举,选出C作为新的term的leader,这样在两个子分区就有了不同Term的两个leader。这时如果有客户端写A时,因为B无法复制日志到大部分Follower,所以日志处于uncommited未提交状态。而同时另一个客户端对C的写操作却能正确完成,因为C是新Leader,它只知道D和E。

当网络通信恢复,B能够发送心跳给C、D、E了,却发现“改朝换代”了,因为C的Term值更啊,所以B自动降为Follower。然后A和B都回滚未提交的日志,并从新的leader那里复制最新的日志。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值