浅谈Raft协议
What is Raft?
Raft is a that is to be easy to . It’s to Paxos in fault- and . The is that it’s into , and it all major for . We hope Raft will make to a wider , and that this wider will be able to a of -based than are today.
以上描述出自Raft官网:,大致意思就是作为分布式场景下的共识算法,Raft与Paxos性能差不多,但是Raft更容易理解,相比Paxos更容易使用。
1、Raft作用
在传统的单机架构的系统中,如果客户端()向服务端请求修改一个数据是非常容易的,直接修改即可,无需考虑其它问题。但是在分布式架构中,同样一个修改操作,就可能会变得很复杂。举个例子,比如一个web系统,服务端部署了3台机器(、、),用户通过页面想要将某个数据value的值由1改成2,请求通过负载均衡算法会落到其中一台服务器,那么.vaule=2,但是其它两台机器上的还是1,这时如果有读请求落到其它两台机器,那么读取到的值就不对了;又或者同时有多个同时对value值进行修改等等,最终都可能会导致、、上的value值不一致,这个问题该如何解决?Raft协议就可以很好的解决以上数据不一致的问题,那么下面就讲下Raft是如何保证数据一致的。
2、节点角色
实现Raft算法的分布式节点有3个角色,或者说3个状态:、、。
有一张图用来表示以上状态直接的流转,这张图摘抄自官网Raft paper
注:上面描述中涉及到了两个超时时间: 和 , 必须要小于 ,否则其它节点肯定就会篡权。
3、Raft两个核心阶段
3.1 领导选举
在前面讲解各个节点角色的时候,已经对领导选举的过程做了介绍了,这里做一个总结:
(1)节点启动后默认是,每个都有一个随机的选举超时时间(150ms-300ms);
(2)某个节点率先到达超时时间后,变成,开始向其它节点进行拉拉票,拉票前先给自己投一票;
(3)其它节点收到节点发来的消息后,会将自己的term和的term进行比较,如果自己的term更大,就投给自己,否则投给,并且重置自己的 ;每收到一个响应就会给自己的票数加1,如果票数超过总节点数的半数,就会成为;
(4)节点为了维护自己的领导地位,会定时发送心跳(该心跳有个专业术语叫 )给其它节点,其它节点接受到心跳后会重置自己的选举超时时间,并将状态转成;
(5)如果节点挂了,或者节点 长时间没有收到心跳,就会重新进行选举,重复上面4个步骤。
用一组图来表示领导选举过程如下:
3.2 日志复制
日志复制是Raft协议保证数据一致的另一个非常重要的手段,领导选举完成后,整个集群就有了一个节点,其余都是节点,如果此时客户端有变更请求过来,只能通过节点进行更新,再由节点将更新复制到其它节点,这个信息时通过心跳来同步给其它节点的。具体的工作过程如下:
(1)客户端发送一个请求set a = 5,节点收到这个请求后先将a=5写入到本地log(追加的方式写入),此时还没有最终提交到内存或者磁盘(此处说的磁盘比如最终持久化到数据库,跟本地log不是一回事)
(2)然后在下一个心跳上将更改发送给其它所有,收到更改后,也是先写入到各自的本地log,然后就会响应—— 一阶段提交;
(3)节点收到超过半数节点的响应后,才提交到自身节点上,提交完成之后就会回复成功,然后再下次心跳会同步给其它节点,其它节点收到心跳后再各自提交到到各自节点,此时集群数据就已经一致了—— 二阶段提交。
用一组图来表示日志复制的过程如下:
4、
集群中每一个节点,都在本地维护着一个快照,里面记录了最后提交的index、当前选举的任期term和数据的最新值,这样在发生故障的时候,就会通过读取快照从而快速恢复到之前的状态。
以上就是Raft算法的简单介绍,只是简单讲解了Raft算法的工作过程,并没有针对各种问题展开分析,其实像挂了,集群就会重新选举,选举过程上面已经介绍了;像脑裂问题,Raft算法的设计上就已经解决了脑裂问题:只要收到超过半数以上的选票时才会成为,这中机制已经保证了不会出现脑裂问题。