Raft协议浅析

1. 简单介绍

raft是paxos算法的一种实现。目标是提供更清晰的逻辑分工使用算法本身更好理解,同时有更高的安全性。Raft能为在计算机集群之间部署有限状态机提供一种通用方法,并确保集群内的任意节点在某种状态转换上保持一致(个人理解就是保证主从的一致性)。
在redis的哨兵模式中就用到了raft协议。

tip:

  • 与paxos最主要的区别:paxos每次遇到一个新的请求会选举新的leader,所以这个leader是短期的。而raft协议选取的leader是永久性的,除非因为网络问题等因素才会进行leader重新选举

2.前置知识

①节点状态

在raft中每个节点都是有对应的状态的,共3种:
● leader 领袖:负责处理外部信息,并通过心跳机制同步给追随者。
● follower 追随者:转发请求给leader,接收来自leader的心跳
● candidate 候选人:当leader不存在时,进行选举

②心跳与选举超时时间

正常情况下,集群中存在leader和follower,leader会定期给follower发送心跳(heartbeat),以至于让其follower知道还在工作。每个follower会维护一个超时选举器(timeout:150ms或300ms),当在timeout后还未收到leader的心跳,则会成功candidate状态并进行选举;若成功收到了来自leader的心跳,则将timeout清零,重新计数。

③任期term count

当选举开始时,term会+1,表示一个新的任期开始,如果选举成功则正常进行工作;如果失败,则终止当前任期,开启新的任期并开启下一次任期(term+1)

④主要解决问题

Raft协议主要解决3个问题:
● 领袖选举
● 记录复写
● 安全性

3.原理

领袖选举 Leader Election

①发生时机

● 起始状态,没有leader
● leader宕机或网络问题
本质都是follower的计时器到期

②原理

  1. 当集群中有节点的timeout(可能是刚开始,也有可能是宕机了)超时后,则该节点从follower状态变为candidate状态,开始进行选举:追随者将自己的term加1,并为自己投递1票,并向集群中的其他集群发起投票请求。(此时其他节点可能处于follower状态或candidate状态)

  2. 当其他节点收到选票请求时,会对选票中的任期信息进行对比,如果选票的任期>自己节点的任期,则会自认落选,并将自己的任期set=选票的任期。如果选票的任期=<自己节点的任期,就意味着在自己已经先于该选票参加过选举了,自己则更应该成功leader

  3. 参与选举的节点在timeout时期内会收到来自其他集群的确认消息,如果超过半数都同一成为leader,则真正的成为leader,否则该节点结束当前任期,进入下一任期的选举,term+1;

  4. Raft每个服务器的超时期限是随机的,这降低伺服务同时竞选的几率,也降低因两个竞选人得票都不过半而选举失败的几率。

视频推荐:raft
看一看这个视频,就懂了

个人对任期与选票的理解:

  • 首先一个term只能投一次vote。
  • candicate是term+1后,马上进行投递vote(投递给自己)
  • follower接收到candicate的vote,判断后(假如成功),则为其投递确认选票,并将自己的term设定为选票的term(term增加变化)。
    为什么每一个term只有一个vote:
  • 可以结合生活例子来看,就如总统选举,也是每个人每届只能投一个。如果每个人每届投两票,都投两个总统,那不是最终就会投出两个相同总统的吗?这就使得这次选举失去了意义。

为什么每个节点的timeout不一样是随机的150ms或100ms。

  • 可以想象一个场景(split vote)【对应官网视频http://thesecretlivesofdata.com/raft/#election】,如果有两个节点同时发生timeout并进行选举,此时他们极有可能在相同时间内收到相同的选票,因为有"每个节点每个任期只能有一票的限制",当两个节点收到相同的选票数量时,他们一定没有收到半数以上的数量,当他们在规定时间内没收到选票,则会进行下一次任期,term+1,重新开始选举。因为timeout不同,所有两个节点下一次首次进行选举时时间就不一样了。

综上:其实只要一个节点的term确定了,那么就暗示着当前的选票就已经投递过了,想要投递新的选票,那么term就必须增加。

即选票的投递一定伴随着term的增加

记录复写 Log Replication

①为什么是集群?

leader提供写服务,follower提供读服务
在互联网整体来看,读远大于写

当写请求打到leader时,我们必须保证整个集群都能够根据这次写请求达到数据的一致性。

②流程

● 当leader收到客户端的请求后,先将修改操作写进自己的日志中,并将日志通过信息随心跳机制发送给其他的follower。自己进入第一阶段
● 其他follower也将此修改操作写到自己的日志中,并回复leader ack。
● 当leader收到半数以上的ack后,给客户端ack,自己本地提交事务,并跟随心跳机制向其他的follower发送提交命令,其他follower收到后,提交本地事务。

③特殊情况

在这里插入图片描述

网络隔离

● 如图所示,A、B机器与CDE被隔离。leaderb因为无法收到半数以上的ack而重复给其他节点发送信息,CDE因无法收到leader心跳,而进行重新选举,并生成新leaderC。
● 如图,他们节点的任期已经不同了,term高的是最新的数据修改
● 当网络恢复,leaderB会发现新的leader,且其term比自己高,自己会退化为followerB,并回滚自身的日志(未提交部分),followerA也会回滚自己的日志(未提交)。同时BA的term任期变为leader的所属任期(为什么?可以类比人类现实:自己的国家选举了新一届的总统,那自己肯定也必须是新一届的人啊,自己所认识的任期也要与leader一致。另一点保证:下次进行leader选举时,表名自己已经获取到了最新的数据)
● 这样就保证了全局的一致性。
在这里插入图片描述

④对于Append Entries Mssage理解

后续………………

raft保证的安全性 Safety

● 选举安全性:每个任期最多只能选出一个领袖。
● 领袖附加性:领袖只会把新指令附加(英语:append)在记录尾端,不会改写或删除已有指令。
● 记录符合性:如果某个指令在两个记录中的任期和指令序号一样,则保证序号较小的指令也完全一样。
● 领袖完整性:如果某个指令在某个任期中存储成功,则保证存在于领袖该任期之后的记录中。
● 状态机安全性:如果某服务器在其状态机上执行了某个指令,其他服务器保证不会在同个状态上执行不同的指令。
前四项保证的原因详见上述算法,状态机安全性则借由下述选举流程的限制所达到。

追随者死机

当某台追随者死机时,所有给它的转发指令和拉票的消息都会因没有回应而失败,此时发送端会持续重送。当这台追随者引导重新加入集群,就会收到这些消息,追随者会重新回应,如果转发的指令已经写入,不会重复写入。

领袖死机

领袖死机或断线时,每个已存储指令必定已经写入到过半的服务器中,此时选举流程会让记录最完整的服务器胜选。其中一个因素是Raft候选人拉票时会揭露自己记录最新一笔的信息,如果服务器自己的记录比较新,就不会投票给候选人。(怎么对比最新信息?根据任期和日志?先比任期再比日志?)

超时期限和可用性

因为Raft启动选举是基于超时,使得超时期限的选择至为关键。若遵守算法的时限需求
广播时间 << 超时期限 << 平均故障间隔
就能达到稳定性。这三个时间定义如下:
● 广播时间 是单一服务器发送消息给集群中每台服务器并得到回应的平均时间,需要测量得到。
● 超时期限 是发动选举的超时期限,由部署Raft集群的人选定。
● 平均故障间隔 是服务器发生故障之间的平均时间,可以测量或估计得到。
广播时间典型是 0.5ms 到 20ms,平均故障间隔通常是用周或月来计算的,所以可以将超时期限设在 10ms 到 500ms。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Java8新特性及实战视频教程完整版Java 8 API添加了一个新的抽象称为流Stream,可以让你以一种声明的方式处理数据。Stream 使用一种类似用 SQL 语句从数据库查询数据的直观方式来提供一种对 Java 集合运算和表达的高阶抽象。Stream API可以极大提高Java程序员的生产力,让程序员写出高效率、干净、简洁的代码。这种风格将要处理的元素集合看作一种流, 流在管道中传输, 并且可以在管道的节点上进行处理, 比如筛选, 排序,聚合等。元素流在管道中经过中间操作(intermediate operation)的处理,最后由最终操作(terminal operation)得到前面处理的结果。 Lambda 表达式,也可称为闭包,它是推动 Java 8 发布的最重要新特性。Lambda 允许把函数作为一个方法的参数(函数作为参数传递进方法中)。使用Lambda 表达式可以使代码变的更加简洁紧凑。Java8实战视频-01让方法参数具备行为能力Java8实战视频-02Lambda表达式初探Java8实战视频-03Lambda语法精讲Java8实战视频-04Lambda使用深入解析Java8实战视频-05Lambda方法推导详细解析-上.wmvJava8实战视频-06Lambda方法推导详细解析-下Java8实战视频-07Stream入门及Stream在JVM中的线程表现Java8实战视频-08Stream知识点总结Stream源码阅读Java8实战视频-09如何创建Stream上集Java8实战视频-10如何创建Stream下集.wmvJava8实战视频-11Stream之filter,distinct,skip,limit,map,flatmap详细介绍Java8实战视频-12Stream之Find,Match,Reduce详细介绍Java8实战视频-13NumericStream的详细介绍以及和Stream之间的相互转换Java8实战视频-14Stream综合练习,熟练掌握API的用法Java8实战视频-15在Optional出现之前经常遇到的空指针异常.wmvJava8实战视频-16Optional的介绍以及API的详解Java8实战视频-17Optional之flatMap,综合练习,Optional源码剖析Java8实战视频-18初识Collector体会Collector的强大Java8实战视频-19Collector使用方法深入详细介绍-01Java8实战视频-20Collector使用方法深入详细介绍-02Java8实战视频-21Collector使用方法深入详细介绍-03.wmvJava8实战视频-22Collector使用方法深入详细介绍-04Java8实战视频-23Collector原理讲解,JDK自带Collector源码深度剖析Java8实战视频-24自定义Collector,结合Stream的使用详细介绍Java8实战视频-25Parallel Stream编程体验,充分利用多核机器加快计算速度Java8实战视频-26Fork Join框架实例深入讲解Java8实战视频-27Spliterator接口源码剖析以及自定义Spliterator实现一个Stream.wmvJava8实战视频-28Default方法的介绍和简单的例子Java8实战视频-29Default方法解决多重继承冲突的三大原则详细介绍Java8实战视频-30多线程Future设计模式原理详细介绍,并且实现一个Future程序Java8实战视频-31JDK自带Future,Callable,ExecutorService介绍Java8实战视频-32实现一个异步基于事件回调的Future程序.wmvJava8实战视频-33CompletableFuture用法入门介绍Java8实战视频-34CompletableFuture之supplyAsync详细介绍Java8实战视频-35CompletableFuture流水线工作,join多个异步任务详细讲解Java8实战视频-36CompletableFuture常用API的重点详解-上Java8实战视频-37CompletableFuture常用API的重点详解-下Java8实战视频-38JDK老DateAPI存在的问题,新的DateAPI之LocalDate用法及其介绍.wmvJava8实战视频-39New Date API之LocalTime,LocalDateTime,Instant,Duration,Period详细介绍Java8实战视频-40New Date API之format和parse介绍

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值