云原生数据库 GaiaDB 的核心技术演进和解析

导读

在越来越强调云原生的环境下,存算分离作为一种新的架构理念,已经是大势所趋。新的技术架构带来新的问题和挑战,百度智能云的云原生数据库 GaiaDB 采用 Quorum 分布式协议、高性能网络、高可靠分布式存储引擎等技术实现更高的性能和可用性。

随着越来越多的企业将业务搬迁至云端,网络、计算和存储资源的弹性伸缩能力变得越来越重要。这些资源的弹性伸缩能力不仅可以帮助云上业务轻松应对业务尖峰,还可以大大降低资源闲置浪费,使得每一分资源都得到充分利用。作为核心基础设施之一,数据库在极致弹性和扩展性方面也进行了多种探索,例如数据的水平分片和分布式化改造。这些方法通过舍弃一部分通用性来增强扩展能力,在配合业务轻度改造的情况下,实现了很显著的体验提升。

然而,作为云上的基础设施,保证用户在迁移前后的业务一致性和可靠性是首要任务。因此,舍弃某些功能或兼容性的路线是无法被接受的。为了解决这个问题,云原生数据库 GaiaDB 应运而生。在保证对原有生态完全兼容的前提下,GaiaDB 使用存算分离技术以及多种内核深度定制优化方案,实现了最大 PB 级数据存储能力与秒级弹性扩缩容能力,使云上业务可以实现全栈弹性伸缩。

595832bf7463cb29f0e304d5206751dc.png

GaiaDB 的存算分离架构采用 Quorum 分布式协议、动态实时 MVCC 技术以及用户态高性能网络等技术,这些技术手段的应用对降低访问延迟和提高读写性能有很好的优化效果。此外,该架构不依赖于任何定制化硬件和基础设施,具有较强的通用性和经济性。

下面分别介绍一下 GaiaDB 的技术应用实践。

1. 分布式协议(DB-Quorum)

GaiaDB 基于「Log is database」的设计理念,即数据的修改只写日志,无需刷新脏页,这极大的降低写放大,简化系统 I/O。GaiaDB 针对 I/O 技术栈进行了充分的优化,从演化路径上看,经历了以下几个阶段:

  1. 分布式文件系统 I/O:

GaiaDB 初期存储使用通用的分布式文件系统作为存储底座存储 innodb redo log 和 innodb page。由于分布式文件系统要实现通用的文件一致性语义,其 I/O 提交和 I/O 收割都存在较多的队列调度和保序逻辑,因此其单线程的异步读写吞吐和延迟都离本地盘有较大差距。

2. 分布式 Raft I/O:

这个阶段,GaiaDB 使用 Raft 三副本进行 redo 日志的持久化,数据页的存储直接使用 peer 三副本持久化到本地文件系统上。日志服务使用 Raft I/O 后,事务写吞吐有了明显提升;但是延时上依然相比本地磁盘性能有较大的gap,特别是长尾问题比较突出。

3. DB-Quorum I/O:

随着时延敏感业务的增多,对 I/O 的时延的要求进一步提升,GaiaDB 舍弃 Raft 协议,采用 Quorum 读写方案,对 I/O 栈进行极致的性能优化。

下面是从 Quorum I/O 替换 Raft I/O 的主要考量:

单次 Redo Raft I/O 网络和磁盘过高,一次 redo 写 I/O 包含以下流程

a) 主库写 Raft leader;

b) Raft leader 发送 Raft 日志;

c) Raft 日志同步到多数派;

d) Raft 日志 apply,数据持久化到 Log Store;

e) 回复主库。

可以发现其中至少两次网络往返,且无法并行。b) d) 为磁盘写且无法并行。并且由于 RPC 和 Raft 的开销,导致 Redo 持久化的时延显著高于传统单机 MySQL 的本地 Redo 落盘时延。

通过深入分析,我们认为:Raft 协议作为类 Paxos 的分布式协议变种,除了保证分布式副本一致性外,其主要时延其实是提供线性一致性语义的额外代价,而在 GaiaDB 中,我们其实已经把线性一致性的约束拆解到了存储层和事务层:

  1. 存储层,我们已经保证如果 lsn = l 的日志已经持久化成功,那么所有 lsn < l 的日志都已经写成功。

  2. 事务层,我们记录当前完成 I/O 收割的最大 lsn,这个 lsn 之前的写事务都能安全提交。

基于以上两点,Quorum 读写模式已经能较好的满足我们的 Redo I/O 的需求。

Quorum 协议在数据库中需要解决以下问题:

  1. 成员变更:在 Quorum 中管理成员实现较为复杂,Gaiadb 相对优雅地结合了 Raft 和 Quorum 的优点,Raft 管理成员变更等控制流,Quorum 管理数据流。

  2. crash safe: 当计算节点宕机时,Quorum 需要有一个数据对齐的过程,Gaiadb 使用两阶段数据对齐协议, prepare 阶段协商数据持久化一致性位点,commit 阶段进行数据补偿。

GaiaDB 在分布式 Quorum 协议中的优化

为了进一步降低远程 I/O 对性能的影响,GaiaDB 对 I/O 流进行了改造,将核心链路上的同步 I/O 改造为异步 I/O,极大了提升了事务吞吐。

2974afc2de88cfb7c357006970a041b3.jpeg

2.高性能智能网络(DB-Network)

在存算分离架构下,网络作为系统 I/O 的重要组成部分,其性能和效率直接影响到整个系统的性能表现。存算分离架构将存储和计算资源分开,使得数据可以在独立的存储节点上进行读写操作,而计算节点则专注于处理计算任务。这种架构的优势在于可以提高系统的扩展性和可靠性,但也增加了网络 I/O 的复杂性和耗时。

在传统的本地 I/O 模式下,数据的读写操作是在本地进行的,因此不需要经过网络传输。而在存算分离架构下,数据的读写操作需要在不同的节点之间进行传输和处理,因此网络 I/O 成为了系统 I/O 中不可或缺的一部分。由于网络传输的耗时相比本地 I/O 要长,因此降低网络 I/O 的耗时成为了存算分离架构必需关注的重点任务之一。

656cc53aa4c6500a858722c3b5e2d3f5.png

2.1 挑战

GaiaDB 采用了 BRPC 网络框架进行场内通信,但在真实业务场景下,平均耗时为微秒级别(400us-500 us 左右),长尾甚至达到了毫秒级别(10 ms+)。这种情况在某些范围内检索的 SQL 查询中尤为严重,因为这些查询需要远程访问大量的数据,从而导致 I/O 长尾成倍放大 SQL 的整体耗时,容易引发系统故障。

为了保障 GaiaDB 大规模稳定上量,缩短远程 I/O 的长尾和平均时延是至关重要的。通常情况优化远程 I/O 有一下两种手段:

  1. 网络优化:采用更快速的网络设备、优化网络路径、减少网络跳数等措施可以降低网络延迟。

  2. I/O 优化:通过优化数据存储和访问模式,减少 I/O 访问延迟。比如采用更高效的存储介质、缓存技术、并行访问等技术。

2.2 解决方案

GaiaDB 网络优化分为两个部分:

  1. 采用网络超时重定向机制,降低单点访问延迟长尾问题

采取了 BackupRequest 机制,即当一个远程 I/O 请求超时时,系统会重试其他副本,从而有效地抑制了单节点长尾问题。这种机制的应用将远程 I/O 的长尾时延由原来的 10 ms 降低到了 5 ms 以内。通过优化网络架构和采用适当的备份机制,BackupRequest 不仅提高了数据的可用性和可靠性,也大大降低了 I/O 延迟,提高了数据库的整体性能。

2. 采用高性能智能网络,减少内核态 TCP 与用户态 TCP 的数据拷贝

GaiaDB 引入了百度内部研发的智能网络。智能网络是一种高性能网络框架,它支持内核态 TCP 和用户态 TCP、RDMA 以及百度内部私有协议等多种协议。智能网络能够根据硬件设备的性能和网络状态,自动选择最优的网络协议和参数,从而最大程度地减少网络传输延迟。

25e30ce7596f6fc27da53b994ad34279.png

智能网络的引入对于降低远程 I/O 的平均时延起到了非常重要的作用。通过智能网络的选择和优化,GaiaDB 能够更好地适应不同的硬件环境,并自动选择最佳的网络协议和参数,进一步提高了数据库的性能和响应速度(E2E 延迟缩短 60%,达到百 us)。

3. 高可靠、高性能分布式存储引擎

存算分离架构是一种现代化的数据库架构设计方式,它的核心思想是将存储和计算分离,以提高系统的可用性、可扩展性和性能。在存算分离架构中,所有需要持久化的数据都被存储在远端的网络附加存储(NAS)、对象存储或分布式文件系统中,或者其他具备高可用能力的分布式存储系统中。而本地存储则只被用来存储临时的、暂态数据,这些数据在需要的时候可以从持久化存储中恢复和重建。

在 GaiaDB 中,「存」所采取的是自研分布式存储系统。该系统结合了 GaiaDB 的数据模型,提供了多版本高可靠高性能的数据存储能力。GaiaDB 的存储系统采用了独特的3副本对等模型,这种模型与传统的 Raft 模型不同。在三副本对等模型中,每个节点都有相同的数据副本,这样可以提高数据的可靠性和可用性。由于没有主从节点的概念,每个节点都可以独立地提供读写服务,从而避免了单点故障的问题。此外,由于对等性,每个节点都可以同时提供 I/O 服务,从而提高了系统的整体性能。

3.1 挑战

存算分离架构为 GaiaDB 带来了新的挑战。在早期阶段,GaiaDB 使用容器模型来存储单副本,并将三个副本部署在不同的容器节点上。然而,由于实测时多跳网络等因素的影响,I/O 性能无法满足要求。为了解决这个问题, GaiaDB 采用了容器+本地磁盘架构模型,虽然满足了 I/O 时延需求,但也带来了新的问题。

  1. 成本问题逐渐显现。在存算分离架构下,需要处理突发流量但又无法共享资源,这容易导致资源浪费和成本上升。例如,每个容器节点分配了 4G 内存作为数据库的一个副本,这无疑增加了系统的整体成本。

  2. 管理问题也是个大问题。当处理的实例数量达到成千上万级别时,容器调度和资源分配等难度上升,实例扩容等耗时也变得更长。例如,每个节点上的端口数量、监控数量以及副本容灾分布规划等都需要大量的人力和物力来管理。

  3. 故障问题也是一个不可忽视的问题。在存算分离架构下,当磁盘或机器出现故障时,数据恢复存在调度管理问题。例如,恢复限速、排队等缺乏全局管理能力,容易造成热点,导致无法提供服务。

3.2 解决方案

为了解决在容器化环境中面临的存储问题,GaiaDB 采用了自主研发的分布式多租户存储方案。该方案不仅在架构上支持多租户模式,还实现了对资源的极大化利用。

GaiaDB 的分布式多租户存储方案将多个集群的数据统一存储在一个系统中。通过资源的闲置调度策略,该方案能够有效地利用存储资源,提高存储空间的利用率。同时,GaiaDB 还对副本管理进行了优化。该方案可根据实例规模、集群磁盘使用率、集群机器负载、集群机架位和集群机器所在交换机等因素进行管理,使存储资源得到充分利用,并满足高性能的存储需求。

然而,随着时间的推移和集群的扩容或缩容等操作,存储系统中的副本分布可能会出现不均衡的现象。为了解决这一问题,GaiaDB 的分布式多租户存储方案能够提供统一的资源均衡策略。这种策略可以在一段时间后自动调整副本的位置,使副本分布更加合理,达到最优的存储效果。

d30f6ff4fdce518685e59f846cd3e237.jpeg

另外,GaiaDB 的分布式多租户存储方案还具备强大的故障恢复能力。当故障发生时,该方案能够实现统一的自动恢复管理。根据待恢复的副本数量等因素,该方案能够合理地分配集群资源,减少资源堆积等问题。这种设计可以在保证数据安全的同时,最大程度地降低存储系统的维护成本,提高系统的可用性和稳定性。

4. 多地多活技术

对于高可用性需求的业务,多可用区部署和多地域部署是常见的解决方案来确保数据库的高可用性。多可用区部署是在多个可用区中复制和备份数据,以避免一个可用区故障导致服务中断,但需考虑数据一致性和同步问题,以及更高的资源和成本。多地域部署是在不同地域的机房中复制和备份数据,网络延迟更大,数据存在秒级别延迟。

4.1 挑战

数据库在多机房和多地域部署的挑战主要来自于数据的一致性、可靠性和延迟问题。以下是对这些挑战的描述:

  1. 数据一致性:在多机房和多地域部署的情况下,保持数据一致性是一个主要挑战。当多个节点在分布式系统中处理数据时,可能会出现数据一致性问题。这种一致性问题通常由网络延迟、系统故障和数据复制延迟等因素引起。为了解决这个问题,可以使用一些技术手段,如分布式事务、一致性保证协议等。

  2. 数据可靠性:在多机房和多地域部署的情况下,数据可靠性是一个重要的挑战。由于地理位置的分散,数据在传输和处理过程中可能会出现更多的错误或丢失的风险。为了提高数据可靠性,可以使用冗余数据复制、分布式数据备份等技术。

  3. 延迟问题:在多机房和多地域部署的情况下,由于地理位置的分散,网络延迟可能会成为一个主要的问题。随着距离的增加,网络延迟会增加,这可能会影响数据库操作的性能和响应时间。为了降低延迟,可以采取一些措施,如优化网络架构、使用低延迟网络协议和缓存技术等。

4.2 解决方案

在数据库多 AZ 的部署中,我们采用了物理同步协议,这种协议可以确保在任意切换过程中不丢失任何数据。通过多 AZ 热活的解决方案,我们可以同时提供服务,从而确保即使在一个区域发生故障时,其他区域也能够继续提供服务。

为了实现低延迟和平滑兼容慢节点的目标,我们采用了就近访问的策略。这个策略能够让用户在访问数据库时自动选择最接近他们的节点,从而最大程度地减少延迟。同时,我们还不断优化数据库的操作和查询,以确保即使在慢节点上也能够平滑地兼容。

在多可用区部署时,GaiaDB 模块的自适应就近访问策略可以感知元数据的变化,并根据这些变化及时切换访问路线。这种策略可以有效地应对各种故障和异常情况,确保数据的可靠性和可用性。

在多地域部署时,GaiaDB 的自研同步组件 Replicator 通过同步 Redo 流来支持 DDL 操作等高级功能。这种方案可以实现主从地域之间的时延小于 2 秒,从而确保数据的实时性和一致性。同时,这种方案还具有良好的可扩展性和灵活性,可以轻松地适应不同地域的需求和变化。

c86369902ab6d9a872e2f81b5df03d9d.png

总结

存算分离已成为流行的架构理念,通过存算分离可以提高数据库的弹性能力,降低存储成本、提高可用性。GaiaDB 在架构演进中采用 Quorum 分布式协议和高性能网络技术降低计算和存储之间的访问延迟,提高并发访问性能;通过高可靠的分布式存储引擎实现 RPO=0,同时利用分布式存储的扩展性提升 I/O 带宽和并发性能。

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

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

相关文章

ElementUI Form:Select 选择器

ElementUI安装与使用指南 Select 选择器 点击下载learnelementuispringboot项目源码 效果图 el-select.vue&#xff08;Select选择器&#xff09;页面效果图 项目里el-select.vue代码 <script> export default {name: el_select,data() {return {options: [{value…

PHP之数据类型的基本介绍

让我为大家介绍一下PHP中的数据类型吧&#xff01; 数据类型有&#xff1a;字符串、整数、浮点数、布尔、数组、对象、NULL、资源类型 我们可以使用gettype去获取数据类型 var_jump()会返回变量的数据类型与值&#xff0c;一般用于开发调试时使用 字符串 字符串是字符序列…

备战蓝桥杯---搜索(优化1)

显然&#xff0c;我们可以用BFS解决&#xff0c;具体实现与八数码类似&#xff1a; 下面是代码&#xff1a; #include<bits/stdc.h> using namespace std; #define N 3000000 string a,b; int hh,dis[N],cnt; struct node{string u,v; }bian[7]; map<string,int>…

Python爬虫requests库详解

使用 requests 上一节中&#xff0c;我们了解了 urllib 的基本用法&#xff0c;但是其中确实有不方便的地方&#xff0c;比如处理网页验证和 Cookies 时&#xff0c;需要写 Opener 和 Handler 来处理。为了更加方便地实现这些操作&#xff0c;就有了更为强大的库 requests&…

docker 网络模型

一、docker的网络模型分为四种 【1】Host(与宿主机共享一个网络)&#xff0c;宿主机的localhost 及 容器内的localhost 【2】Bridge(与宿主机共享一个局域网&#xff0c;有自己的网络&#xff1b;docker运行默认Bridge)&#xff1b;容器内localhost不是宿主机localhost 【3】…

【CSS + ElementUI】更改 el-carousel 指示器样式且隐藏左右箭头

需求 前三条数据以走马灯形式展现&#xff0c;指示器 hover 时可以切换到对应内容 实现 <template><div v-loading"latestLoading"><div class"upload-first" v-show"latestThreeList.length > 0"><el-carousel ind…

双非本科准备秋招(16.1)—— 力扣二叉树

1、101. 对称二叉树 检查是否对称&#xff0c;其实就是检查左节点等不等于右节点&#xff0c;我们可以用递归来做。 如果左右节点都为null&#xff0c;说明肯定对称呀&#xff0c;返回true。 如果一个为null一个不为null&#xff0c;或者左右的值不相等&#xff0c;则为false。…

flutter开发实战-ijkplayer视频播放器功能

flutter开发实战-ijkplayer视频播放器功能 使用better_player播放器进行播放视频时候&#xff0c;在Android上会出现解码失败的问题&#xff0c;better_player使用的是video_player&#xff0c;video_player很多视频无法解码。最终采用ijkplayer播放器插件&#xff0c;在flutt…

3D力导向树插件-3d-force-graph学习001

一、引入文件&#xff1a;下载静态js文件引入 1、**以vue项目测试&#xff0c;在index.html文件中引入静态文件&#xff08;js文件可在官网下载&#xff09;** 2、**也曾尝试用npm包下载引入的方法&#xff0c;总是会有报错&#xff0c;所以采用静态js文件引入的方式** 二、基…

【高质量精品】2024美赛B题22页word版高质量半成品论文+多版保奖思路+数据+前四问思路代码等(后续会更新)

一定要点击文末的卡片&#xff0c;进入后&#xff0c;获取完整论文&#xff01;&#xff01; B 题整体模型构建 1. 潜水器动力系统失效&#xff1a;模型需要考虑潜水器在无推进力情况下的行为。 2. 失去与主船通信&#xff1a;考虑无法从主船接收指令或发送位置信息的情况。…

【AIGC核心技术剖析】DreamCraft3D一种层次化的3D内容生成方法

DreamCraft3D是一种用于生成高保真、连贯3D对象的层次化3D内容生成方法。它利用2D参考图像引导几何塑造和纹理增强阶段&#xff0c;通过视角相关扩散模型执行得分蒸馏采样&#xff0c;解决了现有方法中存在的一致性问题。使用Bootstrapped Score Distillation来提高纹理&#x…

LabVIEW与EtherCAT实现风洞安全联锁及状态监测

LabVIEW与EtherCAT实现风洞安全联锁及状态监测 在现代风洞试验中&#xff0c;安全联锁与状态监测系统发挥着至关重要的作用&#xff0c;确保了试验过程的安全性与高效性。介绍了一套基于EtherCAT总线技术和LabVIEW软件开发的风洞安全联锁及状态监测系统。该系统通过实时、可靠…

jmeter-04创建请求

文章目录 一、发送请求-查看响应流程二、新建请求三、选择请求方式&#xff0c;填写url1.发送get请求当只有请求方式不一样的时候&#xff0c;参数都填写在参数栏里面&#xff0c;GET请求与POST请求的区别&#xff1f; 2.发送post请求2.1 application/x-www-form-urlencoded2.2…

基于深度学习的SSVEP分类算法简介

基于深度学习的SSVEP分类算法简介 1、目标与范畴2、深度学习的算法介绍3、参考文献 1、目标与范畴 稳态视觉诱发电位&#xff08;SSVEP&#xff09;是指当受试者持续注视固定频率的闪光或翻转刺激时&#xff0c;在大脑枕-额叶区域诱发的与刺激频率相关的电生理信号。与P300、运…

C系列-柔性数组

&#x1f308;个人主页: 会编程的果子君 ​&#x1f4ab;个人格言:“成为自己未来的主人~” 目录 ​编辑 柔性数组 柔性数组的特点 柔性数组的使用 柔性数组的优势 柔性数组 也许你从来没有听说过柔性数组这个概念&#xff0c;但是它确实是存在的&#xff0c;C99中&#…

PyTorch 2.2 中文官方教程(十八)

开始使用完全分片数据并行&#xff08;FSDP&#xff09; 原文&#xff1a;pytorch.org/tutorials/intermediate/FSDP_tutorial.html 译者&#xff1a;飞龙 协议&#xff1a;CC BY-NC-SA 4.0 作者&#xff1a;Hamid Shojanazeri&#xff0c;Yanli Zhao&#xff0c;Shen Li 注意…

Hudi学习 6:Hudi使用

准备工作&#xff1a; 1.安装hdfs https://mp.csdn.net/mp_blog/creation/editor/109689143 2.安装spark spark学习4&#xff1a;spark安装_hzp666的博客-CSDN博客 3.安装Scala Hudi学习6&#xff1a;安装和基本操作_hzp666的博客-CSDN博客 spark-shell 写入和读取hudi 2.…

python常用pandas函数nlargest / nsmallest及其手动实现

目录 pandas库 Series和DataFrame nlargest和nsmallest 用法示例 代替方法 手动实现 模拟代码 pandas库 是Python中一个非常强大的数据处理库,提供了高效的数据分析方法和数据结构。它特别适用于处理具有关系型数据或带标签数据的情况,同时在时间序列分析方面也有着出…

基于springboot地方美食分享网站源码和论文

基于springboot地方美食分享网站源码和论文361 首先&#xff0c;论文一开始便是清楚的论述了系统的研究内容。其次&#xff0c;剖析系统需求分析&#xff0c;弄明白“做什么”&#xff0c;分析包括业务分析和业务流程的分析以及用例分析&#xff0c;更进一步明确系统的需求。然…

嵌入式中经典面试题分析

1.关键字static的作用是什么&#xff1f;为什么static变量只初始化一次&#xff1f; 1&#xff09;修饰局部变量&#xff1a;使得变量变成静态变量&#xff0c;存储在静态区&#xff0c;存储在静态区的数据周期和程序相同&#xff0c; 在main函数开始前初始化&#xff0c;在退…