30分钟带你理解 Raft 算法
- 为什么需要 Raft?
- Raft 是什么?
- Raft 的目标
- 前置条件:复制状态机
- Raft 基础
- Leader 选举(选举安全特性)
- 日志复制(Leader只附加、日志匹配)
- 安全
- 学习资料
- 使用 Raft 的应用?
- 扩展:ZooKeeper ZAB 协议
- 扩展:ZooKeeper 是什么?
为什么需要 Raft?
- 要提高
系统的容错率,需要分布式系统 - 分布式系统有多个实例,对于给定的一组操作,需要协议让
所有实例达成一致(分布式一致性) - Paxos 是分布式一致性协议的标准,但难以理解、实现
- Raft 提供了和 Paxos 算法相同的功能,但更好理解、构建实际的系统
Raft 是什么?
- Replicated And Fault Tolerant,
复制和容错 - 管理复制
日志的一致性算法
Raft 的目标
- 简单易理解
- 提供完整的实现系统,减少开发者的工作量
- 保证所有条件下都是安全的,在大部分情况下是可用的
- 常用操作是高效的
前置条件:复制状态机
- Raft 相当于复制状态机中的“
一致性模块” - 一致性模块(Consensus Module):管理来自客户端的指令,接入 log
- 日志(Log)
- 状态机(State Machine):执行日志的指令,得到 Server 状态

Raft 基础
- 节点状态:
Leader(领导者):系统只有一个节点处是 Leader,处理所有客户端的请求并同步给 FollowerFollower(跟随者):只响应其他服务器(Leader、Candidate)的请求Candidate(候选者):在选举领导的时候出现
- term(任期):
- 一段选举的任期(选举开始+正常工作)
- term 号自动 +1
- 如果选票均分,则该 term 直接结束,进入下一个 term
- Raft 中的
「逻辑时钟」,可发现过期信息,规则:- 每个节点会存储当前 term 号,term 编号单调递增
- 节点间通信,交换 term 号
- (1)节点当前 term 号 < 他人 term 号,更新 term 号
- (2)节点当前 term 号 > 他人 term 号,拒绝请求
- (3)Candidate、Leader 发现自己的 term < 他人 term,立即变成 Follower
- 节点通信:使用
RPC- 请求投票(RequestVote) RPCs:选举阶段,Candidate 节点发送给他人
- 附加条目(AppendEntries)RPCs:非选举阶段,Leader 发给所有节点,复制日志+心跳
- 特性(Raft 保证在任何时候都成立)
- 选举安全:对一个给定的 term 号,最多选举出一个 Leader
- Leader 只附加原则:Leader 不会删除、覆盖自己的日志,只会增加
- 日志匹配:若两个日志在相同索引位置的日志的 term 号相同,则日志从头到该索引位置全部相同
- Leader 完整特性:选举出的 Leader,会包含所有已提交的日志
- 状态机安全特性:Leader 已经将给定的索引值位置的日志条目应用到状态机,其他任何服务器都已执行

Leader 选举(选举安全特性)
- Raft 使用心跳机制触发 Leader 选举
- 集群存在 Leader,Leader 节点周期性发心跳包
- 一个 Follower 没有收到任何消息(固定区间随机的时间),发起选举
- 集群启动时,所有节点都处于 Follower 状态
- 节点到达超时时间后,会进入 Candidate 状态,增加自己的 term 号,发送请求投票给自己
- Candidate 状态机
- 节点得票最多的,变成 Leader
- 收到来自其他节点的“声明自己是 Leader”的请求
- 一段时间后,没有获得多数票,也没有收到其他节点的 Leader 通知(平分选票)
- 避免选举的平分选票:随机选举超时时间
- 每个节点随机选择选举超时时间,到达时间后成为 Candidate
- 大多数情况下,只有一个节点率先进入 Candidate
日志复制(Leader只附加、日志匹配)
- Leader 会接收客户端的请求,请求指令作为一个“日志条目”添加到日志中
- 向所有 Follower 发送附加条目 RPC,让他们复制这个日志条目
- 得到大多数节点回复后,Leader 会把日志写入复制状态机,持久化,把执行结果返回给客户端
- 日志非安全的;进入状态机中是安全的(已提交),最终会被所有可用的状态机执行。
index = 7 的日志已经被大多数节点复制,状态为已提交。

安全
- 选举限制(Leader 完整性):每次选举出来的 Leader,必须包含所有已提交的日志
- 只有已经被大部分节点复制的日志,才会变成“已提交”
- 一个 Candidate 必须得到大部分节点投票,才能变成 Leader
- 投票时,节点不会把票投给没有自己的日志新的 Candidate
- Follower 或 Candidate 崩溃:无限重试
- 超时和可用性:broadcastTime(广播时间)<< electionTimeout(选举超时时间)<< MTBF(平均故障间隔时间)
学习资料
使用 Raft 的应用?
- 服务发现框架:consul、
etcd - 日志:
RocketMQ - 数据存储:
Tidb、k8s
扩展:ZooKeeper ZAB 协议
- 支持崩溃恢复的原子广播协议:
ZooKeeper Atomic Broadcast protocol - ZooKeeper 适合
读多写少的场景,客户端随机连到 ZK 集群的一个节点- 从当前节点读
- 写入到 leader,leader 广播事务,半数节点成功才会被提交
整体流程类似于 Raft,只是细节和实现的区别
扩展:ZooKeeper 是什么?
官方定义: A Distributed Coordination Service for Distributed Applications。本质:基于内存的 KV 系统,以 path 为 key。
代码、思维导图笔记链接
代码和思维导图在 GitHub 项目中,欢迎大家 star!
coding 笔记、点滴记录,以后的文章也会同步到公众号(Coding Insight)中,希望大家关注_

30分钟带你理解 Raft 算法的更多相关文章
- 30分钟带你了解Docker
最近一直在忙项目,不知不觉2个多月没有更新博客了.正好自学了几天docker就干脆总结一下,也顺带增加一篇<30分钟入门系列>.网上能够查到的对于docker的定义我就不再重复了,说说我自 ...
- 30分钟带你快速入门MySQL教程
这是一篇真正适合初学者的MySQL数据库入门文章,哪怕你从来没有接触过数据库,或者说你从来没有听说过有数据库这东西,请一定要相信我,我当时就是这么过来的. 如果你刚开始接触MySQL数据库,或者你需要 ...
- 十分钟带你理解Kubernetes核心概念
什么是Kubernetes? Kubernetes(k8s)是自动化容器操作的开源平台,这些操作包括部署,调度和节点集群间扩展.如果你曾经用过Docker容器技术部署容器,那么可以将Docker看成K ...
- 30分钟 带你浅入requirejs源码
因为最近项目想现实一个单页功能,用的是react ,然后看了一下react route,挖槽 gzip后16k? 然后我简单写了一个纯单页(不支持多页的单页,所有入口都经过rewrite跑到index ...
- [转]十分钟带你理解Kubernetes核心概念
本文将会简单介绍 Kubernetes的核心概念.因为这些定义可以在Kubernetes的文档中找到,所以文章也会避免用大段的枯燥的文字介绍.相反,我们会使用一些图表(其中一些是动画)和示例来解释这些 ...
- 30分钟带你了解Springboot与Mybatis整合最佳实践
前言:Springboot怎么使用想必也无需我多言,Mybitas作为实用性极强的ORM框架也深受广大开发人员喜爱,有关如何整合它们的文章在网络上随处可见.但是今天我会从实战的角度出发,谈谈我对二者结 ...
- 30分钟 带你浅入seajs源码
上个星期写了浅入requirejs的, 大家都知道 require是AMD规范(Asynchronous Module Definition) 来 今天我们一起看看 CMD规范(Common Mo ...
- 30分钟带你了解「消息中间件」Kafka、RocketMQ
消息中间件的应用场景 主流 MQ 框架及对比 说明 Kafka 优点 Kafka 缺点 RocketMQ Pulsar 发展趋势 各公司发展 Kafka Kafka 是什么? Kafka 术语 Kaf ...
- 10分钟弄懂Raft算法
分布式系统在极大提高可用性.容错性的同时,带来了一致性问题(CAP理论).Raft算法能够解决分布式系统环境下的一致性问题. 我们熟悉的ETCD注册中心就采用了这个算法:你现在看的这篇微信公众号文章, ...
随机推荐
- Web服务器-并发服务器-Epoll(3.4.5)
@ 目录 1.介绍 2.代码 关于作者 1.介绍 epoll是一种解决方案,nginx就是用的这个 中心思想:不要再使用多进程,多线程了,使用单进程,单线程去实现并发 在上面博客实现的代码中使用过的轮 ...
- 7. 丈母娘嫌我不懂K8s的Service概念,让我去面壁
文章目录 怎么跟你说 Service的出现,就是 解决ip不固定的问题 ,怎么解决呢 ? 听小刘慢慢道来 当Pod宕机后重新生成时,其IP等状态信息可能会变动,Service会根据Pod的Label对 ...
- Spring Cloud 入门教程(二): 服务消费者(rest+ribbon)
在上一篇文章,讲了服务的注册和发现.在微服务架构中,业务都会被拆分成一个独立的服务,服务与服务的通讯是基于http restful的.Spring cloud有两种服务调用方式,一种是ribbon+r ...
- GitHub 上的大佬们打完招呼,会聊些什么?
你好 GitHub!每一位开源爱好者的好朋友「HelloGitHub」 大家好,今儿 HG 有幸邀请到:Lanking 一位亚马逊 AI 软件工程师.开源爱好者和贡献者.他是亚马逊开源的 Java 深 ...
- linux下使用vsftp搭建FTP服务器:匿名登录,账号登录,SSL加密传输
目录 一.关于FTP和VSFTP 二.ftp.sftp.vsftp.vsftpd的区别 三.项目一:搭建一台所有人都可以访问的通用FTP服务器 3.1 项目要求 3.2 项目思路分析 3.3 使用vs ...
- 部署docker镜像仓库及高可用
下载地址: https://github.com/goharbor/harbor/releases 安装harbor服务器: 安装harbor root@harbor-vm1:/usr/loc ...
- Mysql 中的MDL
本文可以结合 MySQL中的事务原理和锁机制 查看. 首先简单了解一下 mysql 的 sql 类型: 1.数据定义语言 DDL:Create.Drop.Alter 操作.用于定义库和表结构的. 2. ...
- .Net Core的简单单元测试基于Mock和自定义
首先创建 使用mock 外部依赖一般用Mock 模拟 下载包 例如 3.1:首先先要使用MOCk来模拟测试方法需要的参数,这一步为 Arrange; 简单的模拟 var mock = new Mock ...
- C#中string类型必填的诡异问题
背景 ASP.NETCore3.0项目,使用Swagger接口文档. 之前的项目都是Swashbuckle.AspNetCore-5.0.0 新项目想尝尝鲜,用最新版Swashbuckle.AspNe ...
- matplotlib学习日记(十一)---坐标轴高阶应用
(一)设置坐标轴的位置和展示形式 (1)向画布中任意位置添加任意数量的坐标轴 ''' 通过在画布的任意位置和区域,讲解设置坐标轴的位置和坐标轴的展示形式的实现方法, 与subplot,subplots ...