为什么说 TiDB 在线扩容对业务几乎没有影响

news2024/9/28 5:28:48

本文讨论了分布式数据库在在线扩容方面的挑战, 详细解释了一般分布式数据库和 TiDB 在扩容机制上的不同。 一般分布式数据库在进行在线扩容时,需要重新平衡数据分布,可能会影响系统的可用性和 IO 消耗。 相比之下,TiDB 的存算分离架构使得扩容对业务影响较小。

作者:爱喝自来水的猫 来源公众号:数据源的技术后花园。

昨天和别人交流 PingCAP TiDB 时,这位同学对“ TiDB 在线扩容对业务几乎没有影响 ” 这一点表示不太理解,惊讶 TiDB 到底是怎么做到的。 细聊下来,发现这位同学是一位主要负责集中式和早期分布式架构数据库的 DBA 人员,比较熟悉 Oracle、Greenplum。 于是我有点理解他的惊讶了,因为 Oracle 和 Greenplum 我也是有一点点经验,本文简单针对一般分布式数据库和 TiDB 在扩容机制上谈一点个人的理解。

一般分布式数据库在线扩容是怎么做的

集中式数据库因为其架构本身的限制,一般来说想要实现在线扩容是比较困难的,这里暂且不予讨论,我们主要了解一下一般分布式数据库的扩容是如何进行的。不管是 Greenplum 这种 MPP 数据库,还是其它的分库分表数据库,为了实现数据的均衡分布,通常需要在表上定义相关的分布键。通过分布键,再结合哈希算法,可以把数据哈希散列到不同的数据节点中,类似于 hash ( key ) % N ( key 代表分布键, N 代表数据节点编号) 。举个例子,假如一个分布式数据库有 3 个数据节点,表的分布键为 ID ( ID 是一个递增序列),那么基于哈希算法散列后数据的分布大致如下图所示:

现在我们需要扩容一个节点,从原来的 3 节点扩容到 4 节点。为了保证原来哈希散列结果的一致性数据需要重新平衡,平衡后的数据分布应该如下面图中所示。可以发现,这个时候大部分的数据基本都搬迁了一遍。先不说数据的迁移是否对业务造成阻塞,光是这现有的大面积数据均衡足以导致整个系统的 IO 消耗极高, 严重影响整个系统的可用性。

Greenplum 在官方文档中还明确指出“ 正在被重新分布的表或者分区会被锁定并且不可读写。当其重新分布完成后,常规操作才会继续 ”。可以明确的说, Greenplum 早期版本里面根本就不 支持所谓的“ 在线 ”扩容。

时代在进步,数据库技术也在进步。为了尽可能实现在线扩容的能力, Greenplum 数据库包括其他的分库分表数据库开始引入一些新的算法来优化此事。 一致性哈希算法 开始被普遍应用,它与传统哈希算法最主要的不同是 不再使用节点编号来进行散列 ,而是使用 2^32 这样一个固定值做取模运算。一致性哈希算法将表中的数据和节点编号映射到一个圆环上,当增加节点时影响的数据范围只是圆环上的一小段数据范围。比如下图中增加节点 4 ,影响的数据只有节点 1 到节点 4 之间的这部分数据。

一致性哈希算法解决了数据重分布时大量数据搬迁的问题,减少了数据搬迁时的网络 IO 和磁盘 IO 。不过要真正实现不影响业务,还需要改进数据重分布内部的机制,比如 重分布时锁表 等问题。

TiDB 的扩容是怎么做的以及为什么它几乎不影响业务?

TiDB 的扩容机制离不开 TiDB 整体的架构实现。作为一个存算分离的原生分布式架构, TiDB 集群主要由三大模块构成:用于集群元数据管理及集群调度的 PD 、用于接收外部请求并解析编译执行 SQL 的计算引擎 TiDB Server 以及用于数据存储以及多副本数据一致性保证的存储引擎 TiKV/TiFlash。

基于存算分离的架构,TiDB 可以单独进行计算层扩容和存储层扩容。计算层的扩容相对简单,因为 TiDB Server 本身是无状态的。TiDB Server 节点不持久化数据,每个节点也是完全对等的,当 TiDB Server 计算资源不够了,只需要增加 TiDB Server 节点,然后修改上层的负载均衡组件将客户端连接均衡分发到新的 TiDB Server 节点即可(目前大多数负载均衡组件都支持动态修改配置)。因此,计算节点的扩容完全不会影响现有的业务。

针对存储节点, TiKV 的扩容与一般分布式数据库的扩容机制是完全不同的,这主要因为 TiKV 是一种 基于 Multi Raft 协议的分布式存储引擎 ,而不是像 Greenplum 或分库分表那种底层是多个 MySQL 或 PG 的单机数据库。

假如某集群要从 3 个 TiKV 节点扩容到 4 个 TiKV 节点,扩容步骤大致可以概括如下:

1.扩容 TiKV 节点 。集群增加一个 TiKV 4 节点,此时 TiKV 4 上没有任何 Region。PD 节点识别到新的 TiKV 节点启动负载调度机制,计算哪些 Region 需要迁移到 TiKV 4。

2.调度算法确定迁移 Region 。PD 节点根据调度机制,确定将哪些 Region 副本迁移到 TiKV 4 上(假如开始 3 个节点上各有 6 个 Region ,平均到 4 个节点后每个节点的 Region 数为 18/4=4~5 个副本)。PD 对 TiKV1~3 上 Region 对应的 Leader 副本发起复制指令。

3.复制 Region 到新节点 。在 TiKV 上创建要复制的 Region 的副本,通过 Raft 机制开始复制数据。此过程中应用读写访问不受影响,不过因复制过程产生的 IO 消耗可能会对性能产生一点影响,不过 TiDB 本身提供了流控,可以动态调整复制的速度。

4.删除多余 Region 。Region 复制完成且数据一致后,PD 将发起删除原有副本指令,保证每个 Region 的副本只有 3 个。

5.Leader 重新均衡 。PD 根据调度机制,需要均衡 Leader 副本,将一部分 Region 的 Leader 切换到新增节点 TiKV 4 上,保证 Leader 的均衡。Leader 切换完成后,读写业务将自动路由到 TiKV 4 上实现业务负载均衡。

上述步骤简单理解下来就是说,TiKV 的扩容是一种 先生成副本再迁移 Leader 的一个过程,扩容对业务有影响的地方主要在于生成副本产生的 IO 消耗以及 Leader 切换的影响。对于前者,数据库有流控机制可以保证对业务几乎没有影响;对于后者,一方面 Leader 的切换本身时间非常短,另一方面当 TiDB 意识到 Region 迁移后也能够通过内部重试保证前端业务的正常执行。因此, 存储节点的扩容也几乎不会影响现有的业务。

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

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

相关文章

五、西瓜书——集成学习

1.个体与集成 集成学习通过将多个学习器进行结合,常可获得比单一学习器显著优越的泛化性能,这对“弱学习器”(weak learner)尤为明显因此集成学习的很多理论研究都是针对弱学习器进行的而基学习器有时也被直接称为弱学习器。 要获得好的集成个体学习器应“好而不同”…

mybatis开发一个分页插件、mybatis实现分页、mybatis拦截器

mybatis开发一个分页插件、mybatis实现分页、mybatis拦截器 通过官网的mybatis插件说明可知,我们可以通过拦截器进行开发一个插件。 例如这样的: UserMapper mapper sqlSession.getMapper(UserMapper.class);// 开始分页MagicPage.startPage(1, 3);//…

八. 实战:CUDA-BEVFusion部署分析-分析BEVFusion中各个ONNX

目录 前言0. 简述1. camera.backbone.onnx(fp16)2. camera.backbone.onnx(int8)3. camera.vtransform.onnx(fp16)4. fuser.onnx(fp16)5. fuser.onnx(int8)6. lidar.backbone.xyz.onnx7. head.bbox.onnx(fp16)总结下载链接参考 前言 自动驾驶之心推出的《CUDA与TensorRT部署实战…

【C++】vector的使用和模拟实现(超级详解!!!!)

文章目录 前言1.vector的介绍及使用1.1 vector的介绍1.2 vector的使用1.2.1 vector的定义1.2.2 vector iterator 的使用1.2.3 vector 空间增长问题1.2.3 vector 增删查改1.2.4 vector 迭代器失效问题。(重点!!!!!!)1.2.5 vector 在OJ中有关的练习题 2.ve…

蓝桥杯倒计时 41天 - KMP 算法

KMP算法 KMP算法是一种字符串匹配算法,用于匹配模式串P在文本串S中出现的所有位置。 例如S“ababac,P“aba”,那么出现的所有位置是13。 在初学KMP时,我们只需要记住和学会使用模板即可,对其原理只需简单理解&#xff…

WiFi模块引领智能家居革命:连接未来的生活

随着科技的快速发展,智能家居正成为现代生活的一部分,极大地改变了我们与家庭环境互动的方式。其中,WiFi模块作为关键的连接技术,在推动智能家居革命中发挥着不可忽视的作用。本文将深入探讨WiFi模块如何驱动智能家居革命。 设备互…

Maven实战(2)之搭建maven私服

一, 背景: 如果使用国外镜像,下载速度比较慢; 如果使用阿里云镜像,速度还算OK,但是假如网速不好的时候,其实也是比较慢的; 如果没有网的情况下更加下载不了. 二, 本地仓库、个人/公司私服、远程仓库关系如下: 三, 下载安装nexus私服 略

如何在Window系统部署VisualSVN服务并结合cpolar实现无公网ip远程访问

文章目录 前言1. VisualSVN安装与配置2. VisualSVN Server管理界面配置3. 安装cpolar内网穿透3.1 注册账号3.2 下载cpolar客户端3.3 登录cpolar web ui管理界面3.4 创建公网地址 4. 固定公网地址访问 前言 SVN 是 subversion 的缩写,是一个开放源代码的版本控制系统…

Mixtral模型解读

Mixtral 8x7B(Mistral MoE) 1.Mistral 7B模型 Mistral 7B模型与Llama2 7B模型结构整体上是相似的,其结构参数如下所示。 细节上来说,他有两点不同。 1.1SWA(Sliding Window Attention) ​ 一般的Attention来说,是Q与KV-Cache做内积&#…

23端口登录的Telnet命令+传输协议FTP命令

一、23端口登录的Telnet命令 Telnet是传输控制协议/互联网协议(TCP/IP)网络(如Internet)的登录和仿真程序,主要用于Internet会话。基本功能是允许用户登录进入远程主机程序。 常用的Telnet命令 Telnet命令的格式为&…

基础算法(四)(递归)

1.递归算法的介绍: 概念:递归是指函数直接或间接调用自身的过程。 解释递归的两个关键要素: 基本情况(递归终止条件):递归函数中的一个条件,当满足该条件时,递归终止,避…

C++11中的auto、基于范围的for循环、指针空值nullptr

目录 auto关键字 使用原因 历史背景 C11中的auto auto的使用案例 auto 指针/引用 同一行定义多个变量 typeid关键字 基于范围的for循环 范围for的语法 范围for的使用条件 指针空值nullptr C98中的指针空值 C11中的指针空值 auto关键字 使用原因 随着程序越…

Decoupled Knowledge Distillation解耦知识蒸馏

Decoupled Knowledge Distillation解耦知识蒸馏 现有的蒸馏方法主要是基于从中间层提取深层特征,而忽略了Logit蒸馏的重要性。为了给logit蒸馏研究提供一个新的视角,我们将经典的KD损失重新表述为两部分,即目标类知识蒸馏(TCKD&a…

JavaSec 基础之五大不安全组件

文章目录 不安全组件(框架)-Shiro&FastJson&Jackson&XStream&Log4jLog4jShiroJacksonFastJsonXStream 不安全组件(框架)-Shiro&FastJson&Jackson&XStream&Log4j Log4j Apache的一个开源项目,是一个基于Java的日志记录框架。 历史…

python学习笔记------元组

元组的定义 定义元组使用小括号,且使用逗号隔开各个数据,数据是不同的数据类型 定义元组字面量:(元素,元素,元素,......,元素) 例如:(1,"hello") 定义元组变量:变量名称(元素,元素,元素,......,元素)…

哈希表是什么?

一、哈希表是什么? 哈希表,也称为散列表,是一种根据关键码值(Key value)直接进行访问的数据结构。它通过把关键码值映射到表中一个位置来访问记录,从而加快查找速度。这个映射函数叫做散列函数&#xff08…

C#与VisionPro联合开发——单例模式

单例模式 单例模式是一种设计模式,用于确保类只有一个实例,并提供一个全局访问点来访问该实例。单例模式通常用于需要全局访问一个共享资源或状态的情况,以避免多个实例引入不必要的复杂性或资源浪费。 Form1 的代码展示 using System; usi…

初阶数据结构之---栈和队列(C语言)

引言 在顺序表和链表那篇博客中提到过,栈和队列也属于线性表 线性表: 线性表(linear list)是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使用的数据结构。线性表在逻辑上是线性结构,也就是说是连…

c++之拷贝构造和赋值

如果一个构造函数中的第一个参数是类本身的引用,或者是其他的参数都有默认值,则该构造函数为拷贝构造函数。 那么什么是拷贝构造呢?利用同类对象构造一个新对象。 1,函数名和类必须同名。 2,没有返回值。 3&#x…

差分题练习(区间更新)

一、差分的特点和原理 对于一个数组a[],差分数组diff[]的定义是: 对差分数组做前缀和可以还原为原数组: 利用差分数组可以实现快速的区间修改,下面是将区间[l, r]都加上x的方法: diff[l] x; diff[r 1] - x;在修改完成后,需要做前缀和恢复…