EasyRAFT

news2024/11/17 0:53:31

EasyRaft 介绍

EasyRaft是Raft(共识算法)的Java实现,主要目的在于提供一种高性能的分布式一致性协议。

覆盖Jraft实现的功能

分布式一致性

分布式一致性 (distributed consensus) 是分布式系统中最基本的问题,用来保证一个分布式系统的可靠性以及容灾能力。简单的来讲,就是如何在多个机器间对某一个值达成一致, 并且当达成一致之后,无论之后这些机器间发生怎样的故障,这个值能保持不变。 抽象定义上, 一个分布式系统里的所有进程要确定一个值 v,如果这个系统满足如下几个性质, 就可以认为它解决了分布式一致性问题, 分别是:

  • Termination: 所有正常的进程都会决定 v 具体的值,不会出现一直在循环的进程。
  • Validity: 任何正常的进程确定的值 v’, 那么 v’ 肯定是某个进程提交的。比如随机数生成器就不满足这个性质。
  • Agreement: 所有正常的进程选择的值都是一样的。

RAFT

RAFT 是一种新型易于理解的分布式一致性复制协议,由斯坦福大学的 Diego Ongaro 和 John Ousterhout 提出,作为 RAMCloud 项目中的中心协调组件。Raft 是一种 Leader-Based 的 Multi-Paxos 变种,相比 Paxos、Zab、View Stamped Replication 等协议提供了更完整更清晰的协议描述,并提供了清晰的节点增删描述。 Raft 作为复制状态机,是分布式系统中最核心最基础的组件,提供命令在多个节点之间有序复制和执行,当多个节点初始状态一致的时候,保证节点之间状态一致。系统只要多数节点存活就可以正常处理,它允许消息的延迟、丢弃和乱序,但是不允许消息的篡改(非拜占庭场景)。

在这里插入图片描述
Raft 可以解决分布式理论中的 CP,即一致性和分区容忍性,并不能解决 Available 的问题。其中包含分布式系统中一些通常的功能:

  • Leader Election
  • Log Replication
  • Membership Change
  • Log Compaction

RAFT 可以做什么

通过 RAFT 提供的一致性状态机,可以解决复制、修复、节点管理等问题,极大的简化当前分布式系统的设计与实现,让开发者只关注于业务逻辑,将其抽象实现成对应的状态机即可。基于这套框架,可以构建很多分布式应用:

  • 分布式锁服务,比如 Zookeeper
  • 分布式存储系统,比如分布式消息队列、分布式块系统、分布式文件系统、分布式表格系统等
  • 高可靠元信息管理,比如各类 Master 模块的 HA

同时RAFT贴近业务的抽象设计,方便适配业务;

EASY RAFT

一个纯 Java 的 Raft 算法实现库, 基于百度 braft 实现而来, 使用 Java 重写了所有功能, 支持:

Leader election and priority-based semi-deterministic leader election.
Replication and recovery.
Snapshot and log compaction.
Read-only member (learner).
Membership management.
Fully concurrent replication.
Fault tolerance.
Asymmetric network partition tolerance.
Workaround when quorate peers are dead.
Replication pipeline optimistic
Linearizable read, ReadIndex/LeaseRead.

个性实现

在EasyRAFT中的自主特殊实现,而没使用通用组件库:

  • 场景特化的LSM数据库
  • 基于原生NIO实现的高并发网络架构
  • 角色抽象设计

主要参考

  • 《In Search of an Understandable Consensus Algorithm》
  • 《数据密集型应用系统设计》
  • 《深入理解Kafka-核心设计与实践原理》
  • 《Kafka源码解析与实践》
  • Kafka源码
  • Nacos源码
  • Netty源码
  • Jraft源码

核心设计

在这里插入图片描述

Role State

单一节点会在三种角色中流转状态,采用了状态模式控制行为,如Leader在包含特殊的行为:

  • 配置变更
  • 同步条目
  • 提交日志
  • 副本日志维护
    在这里插入图片描述

存储

包括Meta存储与Log存储,自主研发的实现:

  • Log 存储,记录 raft 配置变更和用户提交任务的日志,将从 Leader 复制到其他节点上。LogStorage 是定义接口(可实现其它的储存库),包括缓存、读写日志、截断等。
  • Meta 存储,元信息存储,记录 raft 实现的内部状态,比如已提交的偏移量。

RPC

RPC 模块用于节点之间的网络通讯,基于原生NIO、Selector的RPC网络架构,自主研发实现:

  • RPCNetServer: 内置于 Node 内的 RPC 服务器,接收其他节点或者客户端发过来的请求。
  • RpcDistribute: 转交给对应请求分发给指定监听的方法。

技术实现

在这里插入图片描述

整体模块图

RAFT DB

RAFT DB是专门适配Raft协议的储存库,是LSM类型数据库但没有WAL,同时在日志压缩上做了更匹配RAFT的方案。

在这里插入图片描述

详细实现原理

高性能性能基础原理:

  • SSTable:顺序写入
  • Index:MappedByteBuffer(页缓存零拷贝)
  • Meta:MappedByteBuffer(页缓存零拷贝)

此外在并发控制上:

  • 单线程写入。
  • 多线程读取。

而在数据结构上:

  • SSTable: 非定长数据结构依赖Index定位数据。
  • Index:定长的稀疏数据结构,1M即可映射131072条数据。
  • Meta:定长的KV结构。

对比性能

Rocks是一个日志式(LSM)K-V数据库,由FaceBook开发旨在提供高速的数据持久化和读写能力,适用于需要快速存储和检索大量数据的应用程序。使用RocksDB的项目包括Flink、TiKV等;

测试一.插入数据

在此基准测试运行开始时,数据库为空,并逐渐填满。数据加载过程中未读取任何数据。

数据库类型版本平均吞吐量标准差最小最大波动程度置信率同比差率
RaftDB1.0390592.6503469.357 ops/s384407.308395535.1431865.43499.9%100%
RocksDB8.3298498.6602671.176 ops/s293204.765302760.6282498.62099.9%76.4%
测试二.随机读取

测量性能以随机读取现有数据(1000w数据为基础)。

数据库类型版本缓存平均吞吐量标准差最小最大波动程度置信率同比差率
RaftDB1.0关闭102574.6921030.314 ops/s100099.588103989.586963.75799.9%88.1%
RocksDB8.3关闭116429.1393580.538 ops/s108565.503119586.1283349.23799.9%100%
测试三.Raft场景特化案例

此外还有更多的测试用例,不一一展示了

RPC Net

RPC Net是基于JDK NIO实现的RPC架构,设计核心是高并发、可控。

抽象设计

根据Selector模型的事件抽象出,建立连接与读写操作分离的模型。
在这里插入图片描述

线程与消费模型

整体是一个非阻塞的模型,所以不需要很多的线程(读取后投递队列,不处理业务),合适的线程配置是1:4,即一个线程负责接收连接,4个线程负责接收与写入数据等
在这里插入图片描述

更加详细的网络模型

四个队列实现非阻塞的操作,所以该模型可以用少量的线程完成高并发的运转
在这里插入图片描述

并发测试用例
网络框架版本平均吞吐量同比差率
RPC Net1.0349083.983100%
Netty4.1319393.51991.4%

并发控制

项目中有大量的并发风险控制、延迟任务,定制适合场景的多线程工具,精化场景,以下是类图:
在这里插入图片描述

使用指南

基本概念

  • log index 提交到 raft group 中的任务都将序列化为一条日志存储下来,每条日志一个编号,在整个 raft group 内单调递增并复制到每个 raft 节点。
  • term 在整个 raft group 中单调递增的一个 int 数字,可以简单地认为表示一轮投票的编号,成功选举出来的 leader 对应的 term 称为 leader term,在这个 leader 没有发生变更的阶段内提交的日志都将拥有相同的 term 编号。

配置和辅助类

本节主要介绍 Easy RAFT 的配置和辅助工具相关接口和类。核心包括:

Endpoint 表示一个服务地址。
PeerId 表示一个 raft 参与节点。
Configuration 表示一个 raft group 配置,也就是节点列表。

节点

SERVICE_LOCAL_NODES表示一个服务地址,包括 IP 和端口, 并设置了比重,该比重影响优先选举权,如下例:

            Properties properties = new Properties();
            properties.put(ConfigConstants.SERVICE_ID, "id");
            //本地节点&优先选举比重
            properties.put(ConfigConstants.SERVICE_LOCAL_NODES, "1,localhost:9094,[node_weight:500]");
            //集群节点
            properties.put(ConfigConstants.SERVICE_NODES, "2,localhost:9091;3,localhost:9092;3,localhost:9093;");
            ServerConfig serverConfig = new ServerConfig(properties);

配置

其中包括但不限于以下配置:

SERVICE_ROOT_DIR //根目录
SERVICE_QUORUM_RATE //quorum比例
SERVICE_RECORDING_LEVEL//监控等级
SEGMENT_MAX_SIZE//单个Segment大小
SEGMENT_OFFSET_INDEX_MAX_SIZE//Segment稀疏索引大小
SEGMENT_OFFSET_INTERVAL//稀疏索引间隔(默认4k)
LOG_TYPE//日志类型
LOG_CLEAN_OPEN//压缩日志服务
LOG_CLEAN_ALGORITHM//压缩hash算法
......

Leader选举

下图中节点在不同角色流转的核心条件,其中Leader的详细条件包括:

  • Follower时未收到其他Leader的条目同步
  • Candidate发起投票后得到集群节点半数以上的投票
  • 未收到Term大于自己的同步条目
  • 持有最新日志条目

在这里插入图片描述

优化计划

日志提交任务

此优化在独立日志水位后,异步执行同步任务,可预期的结果能够提升并发。

在这里插入图片描述

时间轮延迟任务

相比于JDK-ScheduledThreadPoolExecutor的时间复杂度为O(nlogn),采用此方法时间复杂度能够达到O(1)。
在这里插入图片描述

源码地址

https://gitee.com/weKie/easy-raft.git

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

使用kaliber与imu_utils进行IMU、相机+IMU联合标定

目录 1 标定工具编译 1.1 IMU标定工具 imu_utils 1.2 相机标定工具 kaliber 2 标定数据录制 3 开始标定 3.1 IMU标定 3.2 相机标定 3.3 相机IMU联合标定 4 将参数填入ORBSLAM的文件中 1 标定工具编译 1.1 IMU标定工具 imu_utils 标定IMU我们使用imu_utils软件进行标定…

kepler.gl 笔记:地图样式

1 设置地图样式 2 调整layer的上下顺序 3 地图图层 Label:显示城市、社区等的标签。Road:显示半透明的道路线图层。Border:显示州和大陆边界。Building:显示建筑物轮廓。Water:显示水体。Land:显示公园、山…

Excel 函数大全应用,包含各类常用函数

Excel 函数大全应用,各类函数应用与案例实操。 AIGC ChatGPT 职场案例 AI 绘画 与 短视频制作, Power BI 商业智能 68集, 数据库Mysql8.0 54集 数据库Oracle21C 142集, Office 2021实战, Python 数据分析&#xff0…

批量文件重命名软件 A Better Finder Rename 11汉化for mac

A Better Finder Rename 11是一款功能强大的文件重命名工具,可在Mac操作系统上使用。它提供了简单而直观的界面,帮助用户快速批量重命名文件和文件夹,提高文件管理和组织效率。 以下是A Better Finder Rename 11可能提供的一些主要功能和特点…

U盘怎么设置为只读?U盘怎么只读加密?

当将U盘设置为只读模式时,将只能查看其中数据,无法对其中数据进行编辑、复制、删除等操作。那么,怎么将U盘设置成只读呢? U盘如何设置成只读? 有些U盘带有写保护开关,当打开时,U盘就会处于只读…

摩尔信使MThings设备管理

设备是通信目标设备的本地镜像或服务对象,设备是进行一切MThings功能的基础。通过这种设备集成方法,MThings才具备了多设备、多协议、多通道的调试能力。 1、添加设备 1. 添加设备入口; 2. 选择添加设备所在的通道; 3. 选择添加…

AI智能网关在工业物联网领域有哪些应用优势

随着工业物联网规模的持续扩大,监测个控制需求的增加,传统工业网关越来越难以满足工业物联网的发展步伐。针对规模庞大、设备复杂、自动化智能化水平要求高的工业物联网应用,佰马科技推出了多款搭载AI智能网关,依托强劲处理器性能…

c++视觉----使用多边形包围轮廓

外部矩形边界:boundingRect()函数 #include <opencv2/opencv.hpp> #include <iostream> #include <opencv2/highgui/highgui.hpp> #include <opencv2/imgproc/imgproc.hpp>using namespace std; using namespace cv; #include <iostream> #incl…

美创科技三重数据安全韧性,杜绝删库跑路

从删库到跑路&#xff0c;教训很多&#xff0c;但类似事件近年来总在重复上演&#xff0c;有运维部为此连夜鏖战恢复&#xff0c;更有企业陷入“至暗时刻”&#xff0c;经济受损、名誉蒙尘。 组织单位应该采取怎样的策略和积极主动的方法&#xff0c;避免酿成严重的后果&#x…

视频太大怎么压缩变小?超过1G的视频这样压缩

视频已经成为了我们日常生活中不可或缺的一部分&#xff0c;然而&#xff0c;很多时候&#xff0c;我们可能会遇到视频文件过大&#xff0c;无法在某些平台上传或保存的问题。那么&#xff0c;如何将过大的视频文件压缩变小呢&#xff1f; 下面就给大家分享三款实用的工具&…

python写一个文本处理器

gpt给的latex在xmind中有时候会多出写红色的括号在xmind中会报红&#xff0c;影响观感&#xff0c;用python写一个自动删除],[,(,)的文本处理器&#xff0c;并且带有图形界面&#xff0c;本次程序用来解决gpt发来的latex问题&#xff0c;&#xff1a; import tkinter as tkdef…

MOS管在户用储能上的应用-REASUNOS瑞森半导体

一、前言 户用储能又称家庭储能系统&#xff0c;类似于微型储能电站&#xff0c;是分布式能源&#xff08;DER&#xff09;的重要组成部分&#xff0c;其运行不受城市供电压力影响。户用储能产品系统通常由电池组、电池管理系统&#xff08;BMS&#xff09;、储能变流器&…

聊聊Maven的依赖传递、依赖管理、依赖作用域

1. 依赖传递 在Maven中&#xff0c;依赖是会传递的&#xff0c;假如在业务项目中引入了spring-boot-starter-web依赖&#xff1a; <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId>…

qt5.14.2+VS源码调试记录

在对qt使用时&#xff0c;有时需要对源代码进行调试&#xff0c;方便进行问题定位和debug&#xff0c;但直接安装的qt不能进入qt源码&#xff0c;需要进行一定的操作才能进行源码调试和定位。 源码调试需要对应版本的pdb文件&#xff0c;可以在官网下载&#xff0c;也可找其它…

Linux文件特殊权限与特殊属性

Linux特殊权限 一、粘滞位权限: 功能: 为目录添加粘滞位后该目录中创建的文件和目录只有创建者和超级管理员可以删除。使用场景: 粘滞位权限用于公共目录和临时目录等场景,它提供了一种限制删除和重命名操作的机制,以保护文件的安全性和完整性示例: passwd 程序,允许普…

ESP32-S3上手开发

1、搭建开发环境 首先搭建开发环境&#xff0c;这里采用了windows下集成开发环境ide进行开发&#xff0c;具体的安装方法&#xff1a;ESP-IDF安装配置 这里使用的乐鑫的esp32s3&#xff0c;N16R8 2、esp32s3模块 从上面图中可以看到&#xff0c;N16R8这里使用了外扩16M的fl…

CustomShapes/自定义形状, CustomCurves/自定义曲线, AnimateableData/数据变化动画 的使用

1. CustomShapes 自定义形状视图 1.1 资源图文件 therock.png 1.2 创建自定义形状视图 CustomShapesBootcamp.swift import SwiftUI/// 三角形 struct Triangle: Shape{func path(in rect: CGRect) -> Path {Path { path inpath.move(to: CGPoint(x: rect.midX, y: rect.mi…

Element UI怎么安装呢?

安装 :::warning 注意 后续演示将会在 Vue CLI 搭建的 Vue 项目上进行操作。如需要请查看 Vue CLI 安装 ::: 通过 YARN 命令安装 $ yarn add element-ui完整引入 代表一次性引入所有组件&#xff0c;比较省心省事&#xff0c;但是项目的打包体积也会跟着变大。 // main.js…

python flask接口字段存在性校验函数(http接口字段校验)(返回提示缺少的字段信息)validate_fields()

文章目录 字段存在性校验示例 字段存在性校验 from flask import Flask, request, jsonifyapp Flask(__name__)def validate_fields(data, fields):missing_fields [field for field in fields if field not in data]if missing_fields:return False, f"缺少以下字段: …

c++多态的使用

为什么要使用多态 项目需求&#xff1a; 因为各种不确定原因&#xff0c;包括人为原因&#xff0c;ODU设备会自动的切换到其它类型的设备&#xff0c;而切换后的设备&#xff0c;和原设备有很多不同的地方。如何完美的实现这个切换呢&#xff1f; 解决方案&#xff1a; 使用…