Xline 源码解读(一) —— 初识 CURP 协议

news2024/11/20 3:30:29

01、Xline是什么

Xline 是一款开源的分布式 KV 存储引擎,其核心目的是实现高性能的跨数据中心强一致性,提供跨数据中心的meatdata 管理。那么 Xline 是怎么实现这种高性能的跨数据中心强一致性的呢?这篇文章就将带领大家一起来一探究竟。

02、Xline 的整体架构

我们先来看看 Xline 的整体架构,如下图所示:

从上至下,Xline 可以大致分为三层,分别是

  • 接入层:采用 gRPC 框架实现,负责接收来自客户端的请求。
  • 中间层:可以分为 CURP 共识模块(左)和业务 Server 模块(右),其中:

◦CURP 共识模块:实现了 CURP 共识算法,代码上则对应了 Xline 中的 curp 这个 crate,相应的 rpc 服务定义在 curp/proto 中。 

◦业务 Server 模块:负责实现 Xline 的上层业务逻辑,如负责 KV 相关请求的 Kv Server 以及负责认证请求的 AuthServer 等。代码上则对应了 xline 这个 crate,相应的 rpc 服务定义文件保存在 xlineapi 这个 crate 中。

  • 存储层:负责持久化相关的工作,向上层提供抽象接口,代码上对应了 engine 这个 crate

03、CURP 协议简介

CURP 是什么?

Xline 中所使用的共识协议,即非 Paxos 而非 Raft,而是一种新的名为 Curp 的共识协议,其全称为 “Consistent Unordered Replication Protocol”。CURP 协议来自于 NSDI 2019 的一篇 Paper 《Exploiting Commutativity For Practical Fast Replication》,其作者是来自斯坦福的博士生Seo Jin Park和John Ousterhout教授,John Ousterhout教授同时也是raft算法的作者。

为什么选择 CURP 协议

那为什么 Xline 要使用 CURP 这样一种新的协议,而非 Raft 或者 Multi-Paxos 来作为底层的共识协议呢?为了说明这个问题,我们不妨先来看看 Raft 以及 Multi-Paxos 都存在什么样的问题?

下图是 Raft 协议达成共识的一个时序流程:

在这个时序图中,我们可以了解到 Raft 协议达成共识的流程:

  1. client 需要向 leader 发起一个提案请求。
  2. leader 接收到来自 client 的提案请求后,将其追加到自身状态机日志当中,并向集群中的其他 follower 广播 AppendEntries 请求。
  3. follower 接收到来自 leader 的 AppendEntries 请求后,对其进行日志一致性检查,判断是否可以将其添加到自身的状态机日志当中,是则返回成功响应,否则返回失败响应。
  4. leader 统计所收到的成功响应的数量,如果超过集群节点数量的一半以上,则认为共识已达成,提案成功,否则认为提案失败,并将结果返回给 client。

下图是 Multi-Paxos 协议达成共识的一个时序流程:

在这个时序图中,我们可以了解到 Multi-Paxos 协议达成共识的流程:

  1. client 向 leader 发起一个提案请求。
  2. leader 先在自己的状态机日志上找到第一个没有被批准的日志条目索引,然后执行 Basic Paxos 算法,对 index 位置的日志用 client 请求的提案值进行提案。
  3. follower 接收到来自 leader 发起的提案值后进行决议,接受该提案值则返回成功响应,否则返回失败。
  4. leader 统计所收到的成功响应的数量,如果超过集群节点数量的一半以上,则认为共识已达成,提案成功,否则认为提案失败,并将结果返回给 client。

从上述时序流程来看,不论是 Multi-Paxos 还是 Raft,要达成共识都必然需要经历两次 RTT。之所以是经历两次,是因为它们都基于一个核心假设,命令批准/日志提交后都需要同时满足持久化存储、有序,状态机就能直接执行批准后的命令/应用提交后的日志。但由于网络本身是异步的,无法保证有序性,因此需要 leader 先来执行,以确保不同命令的执行顺序(日志索引),并通过广播获得过半数节点的复制来确保持久化,这无法在一个 RTT 内完成。

而这也是导致 Xline 不选择 Raft 或者 Multi-Paxos 作为底层共识算法的根本原因。Xline 在设计之初便立足于跨数据中心的元数据管理。我们都知道,对于单数据中心而言,其内网的延迟往往都非常的小,只有几毫秒甚至小于 1ms,而对于跨数据中心的广域网下,其网络延迟往往可以达到几十甚至上百毫秒。传统共识算法,例如 Raft 或者 Multi-Paxos,无论在何种状态下,达成共识所需要都需要经过 2 个 RTT。在这种高延迟的网络环境中,传统的共识算法往往会导致严重的性能瓶颈。这不禁引起了我们的思考:任何情况下,两次及以上的 RTT 是否是达成共识的必要条件吗?

而CURP 算法是一种无序复制算法,它将达成共识的场景细分成了以下两类:

fast path: 在无冲突的场景下,在满足持久化存储的前提下,放松对共识的有序性要求并不影响最终的共识的达成。由于 fast path 只要求持久化存储,因此只需要 1 个 RTT 就可以达成共识。我们将 fast path 称之为协议的前端

slow path:在有冲突的场景下,则需要同时保证并发请求的有序性,及持久化存储这两个前提条件,因此需要 2 个 RTT 来达成共识,我们将 slow path 称之为协议的后端。

那读者可能就会有疑问了,这里面的冲突究竟指的是什么呢?让我们用简单的 KV 操作来举个例子。在分布式系统的节点上,我们对状态机所做的操作无非就是读和写,在考虑对状态机的并发操作的情况下,总共可以有读后读,读后写,写后读,写后写四种场景。显然,对于读后读这种无副作用的只读操作而言,任何情况下都不存在冲突,无论是先读还是后读,最终读出来的结果总是一致的。当操作不同的 Key 时,例如 PUT A=1, PUT B=2,那么对于状态机的最终状态而言,不论是先执行 PUT A=1,再执行 PUT B=2,还是反过来,最终从状态机上读出来的结果都是 A=1,B=2。读写混合的场景也是同理,因此当对状态机并发执行的多个操作之间的 key 不存在交集时,我们称这些操作都是无冲突的。反之,如果并发多个操作之间包含了至少一个写操作,同时其操作的 Key 存在交集,这些操作都是冲突的。

fast path 与 slow path

那么 CURP 是如何实现 fast path 和 slow path 的呢?下图是 CURP 算法中集群拓扑的一个简图

让我们先来看看这张图中都有哪些内容:

1. Client:向集群发起请求的 client。

2. Master:对应了集群中的 leader 节点。Master 节点中保存了状态机的日志,其中绿色部分代表的是已经持久化到磁盘当中的日志,而蓝色部分则代表的是保存在内存当中的日志。

3. Follower 节点:对应了上图中黄色虚线框的部分,每个 follower 都包含了一下两个部分:

a. Witness:本质上可以近似地看成是一个基于内存的 HashMap,一方面负责记录当前集群中处在 fast path 流程中的请求,另一方面,CURP 也会通过 Witness 来判断当前的请求是否存在冲突。Witness 中所保存的所有记录都是无序的。

b. Backup:保存持久化到磁盘中的状态机日志。

接着,让我们以图中的例子 PUT z=7 为例,来看看 fast path 的执行流程:

1. client 向集群中所有节点广播 PUT z=7 的请求;

2. 集群当中的节点接受到该请求后,根据角色的不同会执行不同的逻辑:

a. leader 接收到请求后,会立刻将数据 z = 7 写入到本地(也就是状态机日志中的蓝色部分)然后立刻返回 OK。

b. follower 接收到请求后,会通过 witness 判断请求是否冲突。由于此次 z = 7 并不和 witness 中仅有的 y = 5 冲突,因此 follower 会将 z = 7 保存到 witness 中,并向 client 返回 OK。

3. client 收集并统计所接收到的成功响应的数量。对于一个节点数量为 2f + 1 的集群,当接收到的成功响应达到 f+f/2+1 个时,则确认该操作已经持久化到集群当中,整个过程耗时 1 个 RTT。

接下来,在前面 fast path 例子的基础上,让我们以 PUT z = 9 为例,来看看 slow path 的执行流程。由于 z = 9 和前面的 z = 7 相冲突,因此 client 所发起的 fast path 会以失败告终,并最终执行 slow path,流程如下:

1. client 向集群中所有节点广播 PUT z=9 的请求;

2. 集群当中的节点接受到该请求后,根据角色的不同会执行不同的逻辑:

a. leader 接收到请求后,将 z = 9 写入到状态机日志中。由于 z = 9 与 z = 7 相冲突,向 client 返回 KeyConflict 响应,并异步发起 AppendEntries 请求将状态机日志同步到集群的其他节点上。

b. follower 接收到请求后,由于 z = 9 与 witness 中的 z = 7 相冲突,因此会拒绝保存这个提案。

3. client 收集并统计所接收到的成功响应的数量,由于接收到的拒绝响应的数量超过了 f/2,client 需要等待 slow path 的完成。

4. 当步骤 2 中 AppendEntries 执行成功,follower 将 leader 的三条状态机日志(y = 5, z = 7, z=9)都追加到 Backup 后,将 witness 中的相关记录移除,并向 leader 返回成功响应。

5. leader 统计所收到的成功响应的数量,如果超过集群节点数量的一半以上,则认为共识已达成,提案成功,否则认为提案失败,并将结果返回给 client。

04、Summary

Xline 是一款提供跨数据中心强一致性的分布式 KV 存储,其核心问题之一便是如何在跨数据中心这种高延迟的广域网环境中提供高性能的强一致性保证。传统的分布式共识算法,如 Raft 和 Multi-Paxos,通过让所有操作都满足持久化存储和有序性前提来保证状态机一致性。而 CURP 协议则是对达成共识的场景做了更细粒度的划分,将协议分割成了前端(fast path)和后端(slow path),前端只保证了提案会被持久化到集群当中,而后端不仅保证了持久化,也保证了所有保存了该提案的节点会按照相同的顺序执行命令,保证了状态机的一致性。

关于 CURP 协议的简介就到这里,更多的细节欢迎参考我们的其他文章和分享,如下:

Curp 共识协议的重新思考

DatenLord | Xline Geo-distributed KV Storage

Xline是一个用于元数据管理的分布式KV存储。Xline项目以Rust语言写就,欢迎大家参与我们的开源项目!

GitHub链接:

https://github.com/xline-kv/Xline

Xline官网:www.xline.cloud

Xline Discord: 

https://discord.gg/XyFXGpSfvb

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

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

相关文章

GAMES101 OpenCV环境安装

文章目录 Opencv 库编译Step 1.下载源码Step 2. 使用CMake编译Step3. 解决CMake 过程中的报错错误1: 错误的Python版本:错误1 解决办法 错误2:下载ippicv_2020_win_ia32_20191018_general.zip失败错误2 解决办法 错误3:ffmpeg相关文件下载失败…

ROS学习笔记(0):几个重要概念:节点、消息、主题、服务

1、节点(node) 节点是进行运算任务的进程。一个系统可以由很多节点组成,节点也可以称为软件模块。 ROS是以节点的形式开发的,节点是根据其目的,可以细分的可执行程序的最小单位。 主节点 由于机器人的元器件很多&…

win10查看、关闭和开启多个mysql服务

我的之前安装了2个MySQL版本,一个是MySQL8.0.17,一个是MySQL5.7.19 为什么要查看怎么关闭MySQL服务?如果是个人电脑,我觉得开启一个服务相当于开启一个进程,可能会占用部分内存。如果自己是游戏摆烂状态(非学习状态&…

R语言forestploter包优雅的绘制孟德尔随机化研究森林图

在既往文章中,我们对孟德尔随机化研究做了一个简单的介绍。我们可以发现,使用TwoSampleMR包做出来的森林图并不是很美观。今天我们使用R语言forestploter包优雅的绘制孟德尔随机化研究森林图。 使用TwoSampleMR包做出来的森林图是这样的 而很多SCI文章…

qt和vue的交互

1、首先在vue项目中引入qwebchannel /******************************************************************************** Copyright (C) 2016 The Qt Company Ltd.** Copyright (C) 2016 Klarlvdalens Datakonsult AB, a KDAB Group company, infokdab.com, author Milian …

简易评分系统

目录 一、实验目的 二、操作环境 三、实验内容和过程 1.实验内容 2.代码 2.1 用户验证功能 2.2 菜单函数 2.3 评分功能 四、结果分析 总体的输出结果: 保存文件成功截图: 五、小结 一、实验目的 1.巩固和提高学生学过的基础理论和专业知识&am…

windows下安装consul、springboot整合consul

Spring Cloud Consul通过自动配置和绑定到Spring Environment和其他Spring编程模型习语,为Spring Boot应用程序提供Consul集成。通过一些简单的注解,可以快速启用和配置应用程序内的常用模式,并使用Hashicorp的Consul构建大型分布式系统。提供…

使用Dreambooth LoRA微调SDXL 0.9

本文将介绍如何通过LoRA对Stable Diffusion XL 0.9进行Dreambooth微调。DreamBooth是一种仅使用几张图像(大约3-5张)来个性化文本到图像模型的方法。 本教程基于通过LoRA进行Unet微调,而不是进行全部的训练。LoRA是在LoRA: Low-Rank Adaptation of Large Language …

如何通过CRM系统减低客户流失率并提高销售业绩?

销售人员如何提高业绩,减低客户流失率?通过CRM客户管理系统与客户建立良好的客户关系、提升客户体验助力销售人员业绩节节攀升,降低客户流失率。接下来我们就来说一说CRM系统如何实现的? 1.全渠道沟通提升客户体验 只有足够多的…

搜索结果处理

1、排序 #sort排序 GET /hotel/_search {"query": {"match_all": {}},"sort": [{"score": "desc"},{"price": "asc"}] }#找到121.6,31周围的酒店,距离升序排序 GET /hotel/_sea…

前端学习——JS进阶 (Day2)

深入对象 创建对象三种方式 构造函数 小练习 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport"…

python_openpyxl常用语法记录

目录 写在前面&#xff1a; 开始 工作薄 and 工作表 操作单元格 访问&#xff08;调用&#xff09;单个单元格 访问&#xff08;调用&#xff09;多个单元格 保存工作薄 用例 例&#xff1a;简单数据和条形图 操作样式 样式的默认值 单元格样式和命名样式 单元格样…

配置Hadoop_0

配置Hadoop_0 1配置Hadoop100模板虚拟机1.1配置Hadoop100模板虚拟机硬件1.2配置Hadoop100模板虚拟机软件1.3配置Hadoop100模板虚拟机IP地址1.4配置Hadoop100模板虚拟机主机名称/主机名称映射1.5配置Hadoop100模板虚拟机远程操作工具 1配置Hadoop100模板虚拟机 Hadoop100 内存…

编译给IOS平台用的liblzma库(xz与lzma)

打开官方网: XZ Utils 新工程仓库: git clone https://git.tukaani.org/xz.git git clone https://github.com/tukaani-project/xz 旧工程仓库: git clone https://git.tukaani.org/lzma.git 旧版本工程编译: 先进行已下载好的lzma目录 执行./autogen.sh生成configure配置…

233. 数字 1 的个数

题目描述&#xff1a; 主要思路&#xff1a; 寻找1的个数主要分为两个部分&#xff1a;完整的1和取余的1。 完整的1&#xff1a;从个位一直到最高位&#xff0c;例如十位上的1可以出现10次&#xff0c;10-19&#xff0c;然后看他的高位&#xff0c;看看可以出现几轮循环。 取余…

QListWidget 小节

QListWidget 小节 QListWidget 简介举例UI设计头文件源文件 QListWidget 简介 以下是 QListWidget 常用函数的一些说明&#xff1a; addItem(item)&#xff1a;向列表中添加一个项。 addItems(items)&#xff1a;向列表中添加多个项。 clear()&#xff1a;清空列表中的所有项…

射线与物质的相互作用

射线与物质的相互作用 射线与物质的相互作用概要 电离——核外层电子克服束缚成为自由电子&#xff0c;原子成为正离子激发——使核外层电子由低能级跃迁到高能级而使原子处于激发状态&#xff0c;退激发光 射线 致电离辐射 慢化 电离损失&#xff1a;带电粒子与靶物质原子…

this指针/闭包及作用域

一.作用域链 1.通过一个例子 let aglobalconsole.log(a);//globalfunction course(){let bjsconsole.log(b);//jssession()function session(){let cthisconsole.log(c);//Windowteacher()//函数提升function teacher(){let dstevenconsole.log(d);//stevenconsole.log(test1,…

【unity之IMGUI实践】单例模式管理数据存储【二】

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;元宇宙-秩沅 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 秩沅 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a;uni…

FocusState, SubmitTextField 的使用

1. FocusState 输入文本添加焦点状态 1.1 实现 /// 输入文本焦点状态 struct FocusStateBootcamp: View {// 使用枚举enum OnboardingFields: Hashable{case usernamecase password}//FocusState private var usernameInFocus: BoolState private var username: String "…