浅谈Raft协议

What is Raft?
Raft is athat isto be easy to . It’sto Paxos in fault- and . Theis that it’sinto, and itall majorfor. We hope Raft will maketo a wider , and that this widerwill be able toaof-basedthan aretoday.
以上描述出自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不是一回事)