raft算法学习备忘

一致性共识算法

参考:分布式一致性算法应用场景,写了为什么需要共识算法,以及相比于mysql这些主从同步方式的区别。

raft算法简介

一种分布式一致性共识算法的实现方式,机制相比于其它例如paxos来说无论从可读性还是实现机制上要简单很多,并且可以证明其正确性。raft论文只提出想法与证明,具体实现参考官网下面的Where can I get Raft?章节,包含了各种语言的实现。golang最出名的raft算法实现就是etcd团队开源的。
raft算法将集群划分为一主多从,由主节点接收写操作,所以包含了集群自动选主,如果暂时没有选出主节点,集群是不可用状态,等待选出主节点(一般几百ms内就可以选出主节点)。
主节点负责写操作,并将写操作广播给集群来让半数以上节点保存写操作日志,一旦半数同意,就可以

raft算法核心机制

每个节点拥有一个任期term属性

任期term是个数字,可以认为是王朝代号,每次发起选举自增,follower追随者使用leader主节点的任期
在这里插入图片描述

自动选主-保证有主节点对外提供服务

  • 每个节点初始都是follower追随者状态,开启一个选举超时定时器(一般大于给集群广播消息消耗时间,例如内网100ms-300ms),定时器到了还没收到leader心跳消息,就认为leader死了,自己变成candidate发起选举
  • candidate给集群广播要票消息,带上自己当前任期和最新日志索引
  • follower收到要票消息,只要对方任期比自己大且最新日志索引index都和自己一样或者新(raft叫isUpToDate逻辑),并且先来后到没给别人投过票,就直接投票给对方,candidate收集到半数以上投票就变为leader,或者收集到半数以上拒绝或者超时(例如100-300ms)还没统计完投票就变为follower继续开启走心跳监测
  • leader定时给集群发送心跳广播维持自己的统治
    在这里插入图片描述

日志同步

每个提议开始都由leader发起,leader变为日志条目提交,所以每个日志有个自增索引号,与leader所处任期term。
follower需要与主节点leader保持日志条目统一,raft强制让follower纠正自己的日志来保持和leader一致,具体做法为:

  • leader维持了每个follower的日志索引进度,初始等于leader自己的进度,用心跳消息带上维持的follower进度来探测对方进度,对方只要响应不一致,就递减这个进度并带上follower的进度与leader自己的进度之间的日志条目发送给对方继续探测,直到和对方一致。leader会将半数节点都达到的索引处及之前的日志认为已提交成功
  • follower收到心跳消息,比对对方记录的进度的日志索引和任期是否和自己当前记录的一致,一致就将日志条目追加到自己记录上,否则拒绝leader同步让leader再递减索引来探测
    在这里插入图片描述

leader发起提议(写操作)

提议由leader处理,leader会将提议追加到提议日志目录中,所以每个提议日志条目都有自增索引号,任期term+索引index可以确定一个条目,具体操作:

  • leader收到写操作提议,将提议打包成日志条目追加到自己的条目进度里,走上面日志同步 流程来保持日志进度一致

raft算法额外机制

核心机制便于理解raft如何做到共识,而额外机制保证raft算法达到一致性

leader必须提交一笔空写操作

在这里插入图片描述
如果没有这个机制,会像上图所示:

  • (a)时期:如果S1选为leader,向集群复制日志2
  • (b)时期:S1崩溃,此时S5选为leader,准备给集群复制日志3
  • (c)时期:S5还没来得及复制日志3,也崩溃了,S1重新选为leader,重新发起复制日志2并且接收了日志4,在同步给节点S3后又崩溃了
  • (d)时期:S5重新选为leader会要求整个集群应用自己的日志3,但明明©时期S1已经复制了半数日志给集群了,日志2被错误覆盖
  • (e)时期:如果S1当选能立即提交一个日志4的空操作给半数集群,那么S5是无法获得投票再次当选的,因为任期数小于半数集群认同的任期
    这种机制防止了一些崩溃或者网络分区的情况下,旧leader通过旧任期覆盖一些新数据引起线性一致性问题

follower每次随机一个检查心跳超时时间

节点初始都是follower状态,如果一起启动,用一个选举超时时间,会一起变为candidate参与竞选,大家瓜分选票导致竞选失败再次超时重来无限循环。
因此raft规定follower每次检查心跳超时的时间随机等待,防止同时产生竞选。

遵循:broadcastTime ≪ electionTimeout ≪ MTBF,即广播时间小于竞选超时时间小于节点系统不可用时间

已提交日志不能更改

raft算法将日志条目分为已提交段和未提交的临时段,上面的leader纠正follower日志也只能是未提交段

优化raft集群

通过以上说明只是完成了一个固定集群一致性共识,不是真实商用状态,存在诸多问题需要解决。

配置变更(增删节点)

真实环境动态改变节点不可避免,可以将配置变更也作为日志提交,并且新增的节点不参与集群选举

日志条目压缩

随着集群运行很久,日志条目越来越多,假如是个kv数据库,其实保存set key的最后一条写操作即可,因此每个节点可以单独生成已提交日志的快照后删除已提交条目,后续的日志同步涉及快照内的索引就直接以快照同步

处理读请求

将raft集群看成一个整体,写请求打到follower节点会被路由到leader节点处理,那么读请求呢?
假设客户端提交了一笔写操作马上来读这个操作的值,读到的值和写入的一样,这叫线性一致性。raft集群也要满足线性一致性。如果读请求由follower节点处理,可能follower还没接受到leader同步,数据落后;如果由leader处理,leader是保存当前最新的数据,但是读写都在leader又性能不好。
raft论文讨论了往leader节点读,但是有可能该leader是网络分区下的少数派,所以读之前leader要和集群广播确定和集群通信仍有效。
还有其它方法例如将读请求也作为一次提议,这样半数集群通过就可以直接返回数据。例如租约的形式让follower在选举超时内确认没发起竞选期间有处理读的权限,但是依赖时间比对逻辑,时钟可能发生回拨等存在不安全因素。

etcd实现的raft

尝试读了下最新的etcd raft代码,太过于复杂,一个Step函数各种分支走法,于是切换到2.0.0版本学习了下。结合raft论文和etcd的写了个备忘项目:
golang raft (https://github.com/xlkness/lraft): 链接

以下是最新etcd raft Step方法:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/104897.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

3种获取OpenStreetMap数据的方法【OSM】

OpenStreetMap 是每个人都可以编辑的世界地图。 这意味着你可以纠正错误、添加新地点,甚至自己为地图做出贡献! 这是一个社区驱动的项目,拥有数百万注册用户。 这是一个社区驱动的项目,旨在在开放许可下向每个人提供所有地理数据。…

大数据课程K6——Spark的Shuffle详解

文章作者邮箱:yugongshiye@sina.cn 地址:广东惠州 ▲ 本章节目的 ⚪ 了解Spark的定义&&特点&&目的&&优缺点; ⚪ 掌握Spark的相关参数配置; ⚪ 掌握Hadoop的插件配置; 一、Spark Shuffle详解 1. 概述 Shuffle,就是洗牌。之所以…

安防监控平台EasyCVR视频汇聚平台增加首页告警类型的详细介绍

安防监控/视频集中存储/云存储EasyCVR视频汇聚平台,可支持海量视频的轻量化接入与汇聚管理。平台能提供视频存储磁盘阵列、视频监控直播、视频轮播、视频录像、云存储、回放与检索、智能告警、服务器集群、语音对讲、云台控制、电子地图、平台级联、H.265自动转码等…

vue3-ts- element-plus新增组件-过滤

新增组件-所有值为空时过滤 <el-form-item label"家庭成员"><divclass"username-box"v-for"(item, index) in form.namelist":key"index"><div>姓名&#xff1a;<el-input v-model"item.name" placeho…

Java异常

异常体系结构Java异常的分类异常处理异常抛出异常声明异常捕获异常处理流程自定义异常 异常体系结构 .Error&#xff1a;指的是Java虚拟机无法解决的严重问题&#xff0c;比如&#xff1a;JVM的内部错误、资源耗尽等&#xff0c;典型代表&#xff1a;StackOverflowError&#…

uniapp-滑块验证组件wo-slider

wo-slider是一款支持高度自定义的滑块验证组件&#xff0c;采用uniapp-vue2编写 采用touchstart、touchmove、touchend事件实现的滑块组件,支持H5、微信小程序&#xff08;其他小程序未试过&#xff0c;可自行尝试&#xff09; 可到插件市场下载尝试&#xff1a; https://ext.…

Docker搭建个人网盘、私有仓库

1、使用mysql:5.6和 owncloud 镜像&#xff0c;构建一个个人网盘 [rootlocalhost ~]# docker pull mysql:5.6 [rootlocalhost ~]# docker pull owncloud [rootlocalhost ~]# docker run -itd --name mysql --env MYSQL_ROOT_PASSWORD123456 mysql:5.6 [rootlocalhost ~]# doc…

1267. 统计参与通信的服务器

题目描述&#xff1a; 这里有一幅服务器分布图&#xff0c;服务器的位置标识在 m * n 的整数矩阵网格 grid 中&#xff0c;1 表示单元格上有服务器&#xff0c;0 表示没有。 如果两台服务器位于同一行或者同一列&#xff0c;我们就认为它们之间可以进行通信。 请你统计并返回能…

工控机驱动自助检票机,打造轨道交通的智慧未来!

随着城市化进程的加速和人口的不断增长&#xff0c;城市轨道交通建设正日益成为解决交通拥堵、提高交通工作效率的重要举措。然而&#xff0c;仅仅依靠传统的交通设施已经无法满足城市发展的需求&#xff0c;轨道交通智能系统建设成为了不可忽视的发展趋势。 AFC&#xff0c;即…

Git gui教程---第八篇 Git gui的使用 创建一个分支

一般情况下一个主分支下代码稳定的情况下会新建出一个分支&#xff0c;然后在分支上修改&#xff0c;修改完成稳定后再合并到主分支上。 或者几个人合作写一份代码&#xff0c;每个人各一个分支&#xff0c;测试稳定再合并到主分支上。 在git gui选择菜单栏“分支”&#xff0…

Linux之套接字UDP实现网络通信

Linux之套接字UDP实现网络通信 文章目录 Linux之套接字UDP实现网络通信1.引言2.具体实现2.1需要知道的套接字接口1.socket()2.bind()3.recvfrom()4.sendto() 2.2服务器端server.hpp2.3服务器端server.cc2.4客户端Client.cc 1.引言 ​ 套接字(Socket)是计算机网络中实现网络通信…

docker安装clickhouse

安装 docker安装 创建clickhouse目录 mkdir -P /data/clickhouse/datamkdir -P /data/clickhouse/confmkdir -P /data/clickhouse/log 拉取镜像 这里直接拉取最新镜像, 如果需要某个特定版本, 则再拉取的时候指定版本号即可. docker pull clickhouse/clickhouse-server 启动临…

Springboot实现ENC加密

Springboot实现ENC加密 1、导入依赖2、配置加密秘钥&#xff08;盐&#xff09;3、获取并配置密文4、重启项目测试5、自定义前缀、后缀6、自定义加密方式 1、导入依赖 关于版本&#xff0c;需要根据spring-boot版本&#xff0c;自行修改 <dependency><groupId>co…

STM32 CubeMX (第四步Freertos内存管理和CPU使用率)

STM32 CubeMX STM32 CubeMX &#xff08;第四步Freertos内存管理和CPU使用率&#xff09; STM32 CubeMX一、STM32 CubeMX设置时钟配置HAL时基选择TIM1&#xff08;不要选择滴答定时器&#xff1b;滴答定时器留给OS系统做时基&#xff09;使用STM32 CubeMX 库&#xff0c;配置Fr…

java maven项目打jar包发布(精简版)

目录 一、maven打包 二、安装jdk环境 三、安装mysql 四、jar包传输到服务器 一、maven打包 先clean再package target文件夹下面有生成一个jar包 二、安装jdk环境 1、下载jdk cd /usr/local wget https://repo.huaweicloud.com/java/jdk/8u201-b09/jdk-8u201-linux-x64.tar.…

RocketMQ消息存储

一、存储介质 ● 关系型数据库DB Apache下开源的另外一款MQ—ActiveMQ (默认采用的KahaDB做消息存储)可选用JDBC的方式来做消息持久化&#xff0c;通过简单的xmI配置信息即可实现JDBC消息存储。由于&#xff0c;普通关系型数据库(如Mysql)在单表数据量达到千万级别的情况下&a…

uniapp小程序位置信息配置

uniapp 小程序获取当前位置信息报错 报错信息&#xff1a; getLocation:fail the api need to be declared in the requiredPrivateInfos field in app.json/ext.json 需要在manifest.json配置文件中进行配置&#xff1a;

期权是什么?期权的优缺点是什么?

期权是一种合约&#xff0c;有看涨期权和看跌期权两种类型&#xff0c;也就是做多和做空两个方向&#xff0c;走势标的物对应大盘指数&#xff0c;这也是期权与其他金融工具的主要区别之一&#xff0c;可以用于套利&#xff0c;对冲股票和激进下跌的风险&#xff0c;下文介绍期…

安全(权限)框架Shiro概述及原理

1.1 Shiro是什么 Apache Shiro是一个功能强大且易于使用的Java安全&#xff08;权限&#xff09;框架。Shiro可以完成&#xff1a;认证、授权、加密、会话管理、与Web集成、缓存 等。借助Shiro您可以快速轻松地保护任何应用程序——从最小的移动应用程序到最大的Web和企业应用…

opencv 水果识别+UI界面识别系统,可训练自定义的水果数据集

目录 一、实现和完整UI视频效果展示 主界面&#xff1a; 测试图片结果界面&#xff1a; 自定义图片结果界面&#xff1a; 二、原理介绍&#xff1a; 图像预处理 HOG特征提取算法 数据准备 SVM支持向量机算法 预测和评估 完整演示视频&#xff1a; 完整代码链接 一、…