CnosDB有主复制演进历程

news2024/9/25 19:23:52

分布式存储系统的复杂性涉及数据容灾备份、一致性、高并发请求和大容量存储等问题。本文结合CnosDB在分布式环境下的演化历程,分享如何将分布式理论应用于实际生产,以及不同实现方式的优缺点和应用场景。

分布式系统架构模式

分布式存储系统下按照数据复制方式的不同,常分为两种模式:主从模式、无主节点模式。

主从模式

主从模式以Raft分布式算法为代表,Raft 算法是 Diego Ongaro 和 John Ousterhout 于 2013 年发表的《In Search of an Understandable Consensus Algorithm》中提出;从工程案例etcd实现之后,Raft算法开始大放异彩。

Raft分布式算法流程

无主模式

无主模式以亚马逊的Dynamo模型为代表,其理论来源于亚马逊在2007年发表的《Dynamo: Amazon’s Highly Available Key-value Store》,在该论文中论述了一种无主节点的数据库设计方案,像Cassandra、Riak等都是基于此理论实现。

Cassandra数据写入流程

CnosDB整体架构

CnosDB 架构中主要包括了两类进程: cnosdb、cnosdb-meta。cnosdb负责数据的写入、查询、以及存储;cnosdb-meta负责元数据存储,像用户、租户、Database、Table、以及数据分布等相关信息。

Meta服务

CnosDB的Meta服务是有主节点的分布式系统,通过 Raft 一致性协议实现的供CnosDB使用的一套分布式配置中心。作为配置中心要求具有较高的数据一致性,在有主模式下较容易实现这一点,这是我们采用有主模式实现Meta服务的主要原因。

CnosDB对访问频繁的Meta数据在本地有一份Cache,正常情况下直接访问本地Cache,降低用户的请求时延以及对Meta服务的访问压力;通过订阅Meta服务的数据变更日志来更新本地缓存数据。

上面提到Meta数据的本地缓存是通过订阅变更的方式进行同步,这必然会带来本地缓存与Meta服务数据不一致性的问题。对于这个问题我们根据对数据的不同使用场景做了不同处理;在可以容忍这种不一致性的地方直接读取本地缓存,像绝大多数的正常的读写流程都不需要访问Meta服务,这极大降低了用户访问时延;如果需要高度一致性的场景直接访问Meta服务获取最新的数据,像创建数据库、表结构的变更等。

CnosDB服务

CnosDB服务负责数据的写入、读取和存储,是一套类Dynamo的无主节点存储系统。

CnosDB按照两个维度对数据进行分片存储:时间分片与Hash分片。

时间分片:由于时序数据库本身的特征,按照时间维度进行分片有其天然的优势。CnosDB每隔一段时间创建一个Bucket,每个Bucket都有起始、结束时间用于存储对应时间段内的数据。每当系统容量不足时,添加新的存储节点;在创建新的Bucket时也将优先使用空闲容量最多的新节点,已有数据也不需要移动,这完美地解决了集群扩容与数据存储容量的问题。

Hash分片:时间分片完美地解决了存储容量的问题;在一个分布式集群环境下,会有多台机器提供服务,如若每个Bucket只分布在一台机器节点上,则整个系统的写入性能受限于单台机器。时序数据库还有另外一个概念是SeriesKey,按SeriesKey进行Hash分片可以分割成不同的ReplicaSet(复制组),每个ReplicaSet内的一个副本称其为Vnode,每个Vnode分散在不同的存储节点上,一个ReplicaSet内的多个Vnode按照类Dynamo方式进行副本间数据同步;Vnode是CnosDB进行数据分片管理的基本单元,采用Hash分片的方式解决了系统吞吐量的问题。

如下图所示,在时间维度上每隔一段时间创建一个Bucket,每个Bucket有两个复制组(用不同颜色来区分),每个复制组有两个副本(一个Bucket内相同颜色的Vnode有两个)分别落在不同的存储节点上。

当前面临问题

按照时间、Hash两个维度进行分片解决分布式存储下容量与性能问题;但由于每个复制组内的数据复制方式是类Dynamo的无主节点模式,这带来一些新问题:

数据一致性:在无主节点的分布式存储系统中解决数据不一致性问题方式也有很多,像Cassandra中采用以最后写入者为准,Riak中的向量时钟等;再配合读修复、反熵、提示移交(Hinted Handoff)等一整套机制达到数据的最终一致性。这一整套机制实现起来是较为复杂的,也会极大拖累系统的整体性能,CnosDB当前也只是实现了部分机制。

数据订阅与同步:在无主节点的分布式存储系统中由于数据写入无顺序性,这导致做数据订阅也是一个难以解决的问题。在无主节点的模式中数据写入的统一的入口就是计算节点的接口层,但是在计算存储分离的强大背景下,通常计算层都是无状态的,在这一层做数据订阅难以保证订阅服务不丢失数据。

当Raft遇上CnosDB

为解决上述问题,我们转投有主模式寻求解决方案。

半同步方案:最开始我们参考Kafka设计了一个半同步方案。在Kafka中通过下面几个参数来控制服务在不同模式下运行,给用户灵活自由的选择。(不熟悉的读者,具体参数含义可以查阅网络信息)

  1. acks

  2. 复制因子(副本数)

  3. min.insync.replicas

此方案最大优点就是灵活,用户需要什么样的一致性、可靠性等级系统都可以通过参数进行配置;我们考虑到实现的难度、时间关系以及之后的稳定性,暂停了此方案。

其他方案:我们还讨论了主备节点的方案;由于CnosDB系统是多租户的,每个租户甚至每个Database要求的副本数都不一致,导致有些副本节点比较空闲、而像主节点则会压力比较大,造成机器间负载不均衡,资源的浪费等。

最终,我们选择了成熟的Raft方案,确切说是Multi-raft的方式,CnosDB中每个ReplicaSet都是一个Raft复制组。

为什么选择Raft

自采用Raft共识算法实现的etcd发布以后,Raft算法被公认为易于理解、相对易于实现的一套分布式共识算法,在数据的一致性、稳定性、可靠性等方面都得到众多产品的验证。

Raft是有主模式,会很好满足对数据一致性的要求;同时做数据订阅也极其容易(一种方式是作为集群的Learner节点存在,再一种方式是直接读取 Raft Logs)。

再就是CnosDB的Meta服务已经采用Raft。CnosDB主程序再也没有理由不去拥抱Raft。

关于Raft开源社区也有众多开源实现,几乎成为当前分布式系统下的标准算法,我们也并没有必要从头开始造轮子,而是选择了openraft方案。

Raft在CnosDB中应用

在CnosDB 中一个ReplicaSet就是一个Raft复制组,一个ReplicaSet由分布在不同机器上的多个Vnode副本组成,这些Vnode便构成了该Raft复制组的成员节点。

Raft在CnosDB中使用

数据写入过程:在CnosDB中每次写入都对应Raft复制组中的一次提交。服务接收到请求后判断本节点是否是此次写入对应Raft复制组的主节点,不是则进行请求转发;如果是则通过Raft协议进行写入,按照Raft协议在每个Vnode节点下产生一条Raft Log Entry,CnosDB会以WAL的形式记录到此Vnode目录下。

有超过半数Vnode节点记录WAL成功后,由Raft协议驱动进入下一个阶段——Apply阶段;在CnosDB中Apply阶段较为简单,只是写Memcache,主节点Apply成功后就响应客户端成功。

服务重启后Memcache中的数据通过WAL进行恢复。Memcache是由上层的Raft协议驱动刷盘,每次Memcache的刷盘都是作为一个Snapshot而存在。

更详细的过程可以参考Raft协议相关文档。

数据读取过程:根据查询条件,数据读取最终会落到每个Vnode上。在CnosDB的计划中是优先读取主节点的Vnode,这会带来较高的数据一致性;由于CnosDB是一个Multi-raft实现方式,主节点是分散在各个节点并不会造成主从节点负载不均匀的问题。

新的问题

Raft共识算法在如下场景下并没有说明如何处理:

  1. 读写Raft log发生错误

  2. Apply时发生错误

上述两项错误通常为IO错误,发生上述错误时系统将陷入一种未知的状态,当前CnosDB的做法是尽量提前预检查规避错误的发生,也参考了etcd的处理方式如果遇到不可处理的未知场景,将由人工介入处理。

启用Raft算法

在配置文件中只需要把配置项using_raft_replication设置为true即可。

using_raft_replication = true

总结

CnosDB在2.4版本中引入Raft共识算法,在保住了CnosDB高性能、高可用性、易维护性的提前下,将会使得CnosDB 查询具有更高的数据一致性,同时为后面待实现的数据订阅、同步、数据异构处理做足了前期准备。

随着CnosDB各项功能的完善,未来将会在更广泛的使用场景中发挥更大的作用。后期我们会推出更多的测试报告、以及使用场景供大家参考,欢迎各位关注我们,我们共同成长。

CnosDB简介

CnosDB是一款高性能、高易用性的开源分布式时序数据库,现已正式发布及全部开源。

欢迎关注我们的社区网站:https://cn.cnosdb.com

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

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

相关文章

Mybatis-Plus《学习笔记 22版尚硅谷 》——感谢【尚硅谷】官方文档

Mybatis-Plus《学习笔记 22版尚硅谷 》 一、MyBatis-Plus1.简介2.特性3.支持数据库4.框架结构5.官方地址 二、入门案例1.开发环境2.建库建表3.创建工程4.配置编码5.测试查询 三、增删改查1.BaseMapper<T>2.调用Mapper层实现CRUD2.1 插入2.2 删除a、根据ID删除数据b、根据…

MySQL InnoDB 引擎底层解析(一)

6. InnoDB 引擎底层解析 MySQL 对于我们来说还是一个黑盒&#xff0c;我们只负责使用客户端发送请求并等待服务器返回结果&#xff0c;表中的数据到底存到了哪里&#xff1f;以什么格式存放的&#xff1f;MySQL 是以什么方式来访问的这些数据&#xff1f;这些问题我们统统不知…

Web安全研究(五)

Automated WebAssembly Function Purpose Identification With Semantics-Aware Analysis WWW23 文章结构 introbackgroundsystem design abstraction genapplying abstractionsclassifier data collection and handling data acquisitionstatistics of collected datamodule-…

Python---return返回值

return返回值 返回值&#xff1a;很多函数在执行完毕后&#xff0c;会通过return关键字返回一个结果给 调用它的位置。 return 英 /rɪˈtɜːn/ n. 回来&#xff0c;返回&#xff1b; 思考&#xff1a;如果一个函数需要两个return (如下所示)&#xff0c;程序如何执行&…

【数据结构(二)】单链表(3)

文章目录 1. 链表介绍2. 单链表应用实例2.1. 顺序添加方式2.1.1. 思路分析2.1.2. 代码实现 2.2. 按照编号顺序添加方式2.2.1. 思路分析2.2.2. 代码实现 3. 单链表节点的修改3.1. 思路分析3.2. 代码实现 4. 单链表节点的删除4.1. 思路分析4.2. 代码实现 5. 单链表常见面试题5.1.…

基于灰狼算法(GWO)优化的VMD参数(GWO-VMD)

代码的使用说明 基于灰狼算法优化的VMD参数 代码的原理 基于灰狼算法&#xff08;Grey Wolf Optimizer, GWO&#xff09;优化的VMD参数&#xff08;GWO-VMD&#xff09;是一种结合了GWO和VMD算法的优化方法&#xff0c;用于信号分解和特征提取。 GWO是一种基于群体智能的优化…

数据结构:红黑树讲解(C++)

红黑树 1.前言2.红黑树简述2.1概念2.2性质 3.红黑树的插入3.1关于新插入节点的颜色3.2节点的定义3.3插入新节点3.4判断插入后是否需要调整3.5插入后维持红黑树结构&#xff08;重点&#xff09;3.5.1cur、p、u为红&#xff0c;g为黑3.5.2cur、p为红&#xff0c;g为黑&#xff0…

openGauss学习笔记-127 openGauss 数据库管理-设置账本数据库-修复账本数据库

文章目录 openGauss学习笔记-127 openGauss 数据库管理-设置账本数据库-修复账本数据库127.1 前提条件127.2 背景信息127.3 操作步骤 openGauss学习笔记-127 openGauss 数据库管理-设置账本数据库-修复账本数据库 127.1 前提条件 系统中需要有审计管理员或者具有审计管理员权…

golang中的并发模型

并发模型 传统的编程语言&#xff08;如C、Java、Python等&#xff09;并非为并发而生的&#xff0c;因此它们面对并发的逻辑多是基于操作系统的线程。其并发的执行单元&#xff08;线程&#xff09;之间的通信利用的也是操作系统提供的线程或进程间通信的原语&#xff0c;比如…

Vite - 静态资源处理 - json文件导入

直接就说明白了 vite 中对json 文件直接当作一个模块来解析。 可以直接导入使用&#xff01; 可以直接导入使用&#xff01; 可以直接导入使用&#xff01;json文件中的key&#xff0c;直接被作为一个属性&#xff0c;可以单独被导入。 因此&#xff0c;导入json文件有两种方式…

72. 编辑距离(动态规划)

题目 题解 class Solution:def minDistance(self, word1: str, word2: str) -> int:# 定义状态&#xff1a;dp[i][j]表示将word1[0:i]转换成word2[0:j]所使用的最少操作数dp [[0 for j in range(len(word2)1)] for i in range(len(word1)1)]# badcase: dp[0][j] j, dp[i]…

kaggle新赛:SenNet 3D肾脏分割大赛(3D语义分割)

赛题名称&#xff1a;SenNet HOA - Hacking the Human Vasculature in 3D 赛题链接&#xff1a;https://www.kaggle.com/competitions/blood-vessel-segmentation 赛题背景 目前&#xff0c;人类专家标注员需要手动追踪血管结构&#xff0c;这是一个缓慢的过程。即使有专家…

defer和async

如果两个属性浏览器都不兼容&#xff0c;推荐把<script>标签放到底部 一般情况下&#xff0c;浏览器在解析html源文件时&#xff0c;如果遇到外部的<script>标签&#xff0c;解析过程就会先暂停&#xff0c;这时会对script进行加载&#xff0c;执行两个过程&…

【Linux进程】进程等待 与 进程替换 原理与函数使用

文章目录 一、进程等待1.1 意义 / 必要性1.2 进程等待的函数&#xff08;wait / waitpid&#xff09;1.3 status参数1.4 获取子进程status1.5 进程的阻塞等待与非阻塞等待 二、进程替换2.1 引言2.2 进程替换原理2.3 替换函数 一、进程等待 1.1 意义 / 必要性 为什么要有进程等…

【【VDMA彩条显示实验之二】】

VDMA彩条显示实验之二 这一篇紧接上一篇文章 我们添加一个 VID_out 的 IP核 其实 相对来说 就是我们把 传进来的串行信号 转化成并行输出各个信号 &#xff08;把 Stream 的 输出信号流转化成在 RGB上 输出的 格式 &#xff09; 下面是对IP核的简介 AXI4-Stream to Video Out…

八、Linux关机重启和用户登录注销

1.Linux关机、重启 基本介绍 shutdown -h now 立即进行关机 shutdown -h 1 “hello&#xff0c;1分钟后会关机了”(h&#xff1a;halt) shutdown 默认就是&#xff08;shutdown -h 1&#xff09; shutdown -r now 现在重新启动计算机(r : reboot) halt 关机&#xff0c;作用和…

Tomcat无法映射到activiti-app导致activiti无法启动页面

原因之一&#xff1a;JDK版本与Tomcat版本不匹配&#xff0c;jdk8 yyds 我使用的是JDK11&#xff0c;Tomcat是9.0的&#xff0c;都是最新的&#xff0c;但还是不行&#xff0c;最后JDK改为8&#xff0c;tomcat的cmd后台没有报错&#xff0c;activiti-pp也可以正常访问了,很神奇…

基于RK3588全高端智能终端机器人主板

一、小尺寸板型设计 该款主板为小型板&#xff0c;尺寸仅为125*85mm&#xff0c;更小更紧凑&#xff0c;可完美适应各类高端智能自助终端&#xff1b; 二、八核高端处理器 采用RK3588S八核64位处理器&#xff0c;8nm LP制程&#xff0c;主频最高达2.4GHz&#xff0c;搭载Andr…

Python大数据之linux学习总结——day11_ZooKeeper

ZooKeeper ZK概述 ZooKeeper概念: Zookeeper是一个分布式协调服务的开源框架。本质上是一个分布式的小文件存储系统 ZooKeeper作用: 主要用来解决分布式集群中应用系统的一致性问题。 ZooKeeper结构: 采用树形层次结构&#xff0c;ZooKeeper树中的每个节点被称为—Znode。且树…

Web实战:基于Django与Bootstrap的在线计算器

文章目录 写在前面实验目标实验内容1. 创建项目2. 导入框架3. 配置项目前端代码后端代码 4. 运行项目 注意事项写在后面 写在前面 本期内容&#xff1a;基于Django与Bootstrap的在线计算器 实验环境&#xff1a; vscodepython(3.11.4)django(4.2.7)bootstrap(3.4.1)jquery(3…