Raft协议

Raft协议基于日志实现了一致性

实现备份的是机制:复制状态机Replicated State Machine,如果两个相同的、确定性的状态机从同一状态开始,以相同顺序输入相同的日志,则两个状态机最终也会保持一致

Raft了实现Consensus Module

Consensus Module作为一致性模块对外服务,负责接收客户端的消息,响应请求,并追加到本地日志,一致性模块保证每个机器上的log的一致性

请求到来时,带上(term,commitindex)和append log 去要求Follower追加消息,Follower会先判断(term,index)是否和当前最大的消息相同,如果相同就会追加,否则会拒绝

一致性模块负责复制消息到其他服务器节点,本地日志commit成功后立即应用到状态机

CNew用于服务器增加或者减少节点的情况

Leader:处理与客户端交互,处理消息

Follower:选民,转发请求到leader

Candidate:候选人,可以参选成为leader,不是所有Follower都能成为Candidate,只有数据较完整的才可以。如果Candidate发现自己的term落后了就会退回到Follower

RequestVote:选举期间的RPC消息

AppendEntries:leader选出后向Follow复制日志的RPC消息,心跳也是AppendEntries,不过日志内容为空

raft协议原理

  • Election Safty:每个任期只有一个leader
  • Leader Append-Only:leader仅新增日志,不能重写或删除日志条目
  • Log Match:如果两个日志的term和index相同,则两个状态机的完全相同
  • Leader Completeness:如果一条日志被Commit过,那么大于该日期条目的term的所有节点,都应该有该条目
  • State Machine Safty:如果某个server将日志交由状态机处理了,那么所有server交由状态机执行的日志条目数量完全相同

Election Safty

  • 竞选leader时,Candidate获取过半的票数,就能成为leader

    如果出现大家都投票给自己或两台机器各获得一般的票数,则随机Sleep重新选举
  • 先到先得
  • Follower遵循规则:选举term比自己大 -> index 比自己大,否则不会选举该Candidate
  • 随机超时,更快选出leader
  • 如果给candidate投票了,需要持久化记录投给谁了;否则如果follower重启,可能导致前后投票不相同

Log Match

leader向follower复制日志时,会带上当前最新的(该日志前)term和index,follower接收到请求后,会先比对自身最新的日志的term和index,匹配时才会追加,否则拒绝,这时leader会往前找term 和index,尝试和follower匹配成功,然后从该位置开始复制日志到follower

Leader completeness

不能提交之前任务内的日志作为Commit 点

选主

如果一个Follower在一定时间没有收到Leader的心跳,则开始重新选主

Follower把自己的状态变更为Candidate,并递增本地term,并持久化,向其他机器拉票,并给自己投票,开始等待,直到

  • candidate赢得选主,获得多数派的选票
  • 其他机器成为leader,心跳发现term大于等于本机term,自动变为Follower
  • 超时未能选主成功
  • 确保包含所有commit日志的主机才能成为candidate

    选举时candidate至少要和多数派主机通信,当发现candidate比本机的term,logindex还小时,follower就会拒绝投票

如何判断commit与否

leader发现log已经被多数派的主机写盘了,就认为commited

CNew,集群拓扑变化

将Cnew发送出去,如果Follower发现自己已经不在拓扑结构中,则退出

  • 生成logEntry Cold U Cnew
  • 推送给Follower
  • 过半则Commit
  • 生成CNew Log Entry,推送到所有Follower
  • Follower更新Cnew配置,了解自己在集群中的位置,如果新配置中已无当前节点,则自动退出
  • Leader收到多数派确认后,回复客户端执行命令成功

No op Entry

leader在选举刚结束后,可能有一些Entry是已经提交的,有一些是还未提交的,因此需要提交一个No op Entry来确保和Follower达到一致了,同时,也为了防止客户端来了新请求后不能及时到达

疑问

到底是如果commit的,Raft是如果保证状态机一致性的

情况1:

client - > leader -> Log AppendEntries - > 多数派确认 ->已经commited -> 返回client:成功

由于已经到多数机器上,即使重新选主,也一定会带有最新的log

但是这种情况呢

情况2:

client - > leader -> Log AppendEntries - > 未获取多数派确认 ->不算作Commited -> 返回client:失败重试

返回给client失败了,此时若leader断开网络,可能出现部分确认的实例被选中为leader?岂不是实际成功了

Raft维护的以下属性是否可以解释此问题:

  1. 如果在不同的日志文件内有2个条目有相同的index和term, 它们保存着相同的命令;
  2. 如果在不同的日志文件内有2个条目有相同的index和term,那么之前的所有条目都是相同的;
  3. 只有被多数派follower确认了才会认为Commit了

依据上述特性,出现情况2时,不满足特性3,client会收到执行失败的响应,此时应该做的是不断重试,直到成功,也就是说raft协议允许情况3,也要求client如果想要强一致性,就得不断的重试

raft保证了已提交日志的一致性

follower发现自己已提交的term和logindex 比leader还大怎么办?

leader退化成follower

leader何时告诉follower log已提交了?

在下一个心跳告诉所有follower更新Commited项目

Raft约束日志是连续commit的,leader维护最大已经commit的日志id,并将这个信息附加到AppendEntries告知follower,follower了解到之后即可将本机已有的且已经commit的日志应用到本地的状态机。

参考文章

http://thinkinjava.cn/2019/01/12/2019/2019-01-12-lu-raft-kv/

https://raft.github.io/

https://blog.csdn.net/weixin_39843367/article/details/82498536

https://blog.csdn.net/baijiwei/article/details/78760308

https://www.jdon.com/artichect/raft.html

http://ifeve.com/解读raft(二-选举和日志复制)/

Raft协议备注的更多相关文章

  1. Raft协议实战之Redis Sentinel的选举Leader源码解析

    这可能是我看过的写的最详细的关于redis 选举的文章了, 原文链接 Raft协议是用来解决分布式系统一致性问题的协议,在很长一段时间,Paxos被认为是解决分布式系统一致性的代名词.但是Paxos难 ...

  2. MIT-6.824 Raft协议

    摘要 raft是一种比paxos容易理解的一致性算法,实现起来比paxos简单许多.本文前部分描述算法的细节,后部分尝试探讨下该算法的原理. 算法描述 raft算法之所以简单的原因之一是它将问题分解成 ...

  3. Raft协议学习笔记

    目录 目录 1 1. 前言 1 2. 名词 1 3. 什么是分布式一致性? 3 4. Raft选举 3 4.1. 什么是Leader选举? 3 4.2. 选举的实现 4 4.3. Term和Lease ...

  4. [搜狐科技]由浅入深理解Raft协议

    由浅入深理解Raft协议 2017-10-16 12:12操作系统/设计 0 - Raft协议和Paxos的因缘 读过Raft论文<In Search of an Understandable ...

  5. Paxos、ZAB、RAFT协议

    这三个都是分布式一致性协议,ZAB基于Paxos修改后用于ZOOKEEPER协议,RAFT协议出现在ZAB协议之后,与ZAB差不多,也有很大区别. 1. Paxos 分布式节点分为3种角色, Prop ...

  6. Paxos算法与Zookeeper分析,zab (zk)raft协议(etcd) 8. 与Galera及MySQL Group replication的比较

    mit 分布式论文集 https://github.com/feixiao/Distributed-Systems wiki上描述的几种都明白了就出师了 raft 和 zab 是类似的,都是1.先选举 ...

  7. RocketMQ 多副本前置篇:初探raft协议

    目录 1.Leader选举 1.1 一轮投票中,只有一个节点发起投票的情况 1.2 一轮投票中,超过一个节点发起投票的情况 1.3 思考如何实现Raft选主 2.日志复制 Raft协议是分布式领域解决 ...

  8. 基于 raft 协议的 RocketMQ DLedger 多副本日志复制设计原理

    目录 1.RocketMQ DLedger 多副本日志复制流程图 1.1 RocketMQ DLedger 日志转发(append) 请求流程图 1.2 RocketMQ DLedger 日志仲裁流程 ...

  9. raft协议-分布式环境下的数据一致性问题

    阅读了一个有意思的ppt,是Standford大学发表的raft协议 网址:http://thesecretlivesofdata.com/raft/ 下面自己总结下咯: 1.raft是一个实现了解决 ...

随机推荐

  1. volatile域浅析

    内存模型的相关概念 计算机中执行程序时,每条指令都是在CPU中执行,执行指令的过程必然会涉及到数据的读取和写入.而程序运行时的数据是存放在主存(物理内存)中,由于CPU的读写速度远远高于内存的速度,如 ...

  2. php第三天-数组的定义,数组的遍历,常规数组的操作

    0x01 数组分类 在php中有两种数组:索引数组和关联数组 索引数组的索引值是整数,以0开始.当通过位置来标识东西时用索引数组. 关联数组是以字符串作为索引值,关联数组更像操作表.索引值为列名,用于 ...

  3. HashMap,HashSet,HashTable,LinkedHashMap,LinkedHashSet,ArrayList,LinkedList,ConcurrentHashMap,Vector 区别

    ConcurrentHashMap是弱一致性,也就是说遍历过程中其他线程可能对链表结构做了调整,因此get和containsKey返回的可能是过时的数据 ConcurrentHashMap是基于分段锁 ...

  4. java.lang.illegalArgumentException异常

    今天在使用spring3.2的时候,配置好注解开发后,运行出现异常 java.lang.illegalArgumentException 经查为 JRE 版本域spring3.2不兼容所致, 将项目J ...

  5. Centos-对比文件差异-diff

    diff 比较文件差异 相关选项 -c 显示全部内容,并标记不同之处 -b 忽略行尾空格,并认为字符串中一个或多个空格视为相同 -r  当比较双方都是目录时,会比较子目录中的文件 -s 当两个文件相同 ...

  6. 0921 LCA练习

    1.poj 1330 数据结构中的树,在计算机科学中是非常重要的,例如我们来看看下面这棵树: 在图中我们对每个节点都有编号了. 8号节点是这棵树的根.我们定义,一个子节点向它的根节点的路径上,任意一个 ...

  7. go分库分表 主从分离例子

    网上有很多介绍分库分表的文章,方法很多: 分区表切分 垂直切分 水平切分 区间切分 取模切分 这里不细说 分库分表简单,但后期会带来一系列的难题: 事务 Join 分页 数据库: master和sla ...

  8. Linux系统编程 —时序竞态

    时序竞态 什么是时序竞态?将同一个程序执行两次,正常情况下,前后两次执行得到的结果应该是一样的.但由于系统资源竞争的原因,前后两次执行的结果有可能得到不一样的结果,这个现象就是时序竞态. pause函 ...

  9. 制作u盘启动盘

    制作u盘启动盘 如果是想要制作 windows 系统启动盘,windows 官网提供途径,这里不在赘述. 以下讨论制作 centos 系统启动盘,需要 centos 系统文件,开源,可从官网下载得到. ...

  10. spring-boot-route(九)整合JPA操作数据库

    单调的增删改查让越来越多的程序员感到乏味,这时候就出现了很多优秀的框架,完成了对增删改查操作的封装,只需要简单配置,无需书写任何sql,就可以完成增删改查.这里比较推荐的是Spring Data Jp ...