分库分表——从理论到最佳实践

目录

  • 1、为什么要分库分表?
  • 2、切分方案有哪些?
    • 2.1 分库
      • 2.1.1 垂直分库
      • 2.1.2 水平分库
    • 2.2 分表
      • 2.2.1 垂直分表
      • 2.2.2 水平分表
    • 2.3 分库分表
  • 3、数据水平分片方法
    • 3.1 Hash分片
    • 3.2 一致性Hash分片
    • 3.3 Range分片
  • 4、分库分表的挑战
    • 4.1 分布式id
    • 4.2 分布式事务
    • 4.3 动态扩容
    • 4.4 跨库关联问题
    • 4.5 服务、数据平滑迁移
    • 4.6 数据库基本的增删改功能
    • 4.7 子表分库分表
  • 5、项目实战

1、为什么要分库分表?

随着业务的不断发展,系统数据量不断增加,即便正确设置了索引,仍然无法掩盖因为数据量过大从而导致的数据库性能下降的事实。 对于单台 MySQL 服务器来说,硬件资源(如存储容量、连接数与处理能力)是有限的。当数据量过大或读写操作并发过高时,超出了单服务器的性能瓶颈,可能会对系统的稳定性产生严重隐患,甚或导致系统整体不可用。

在仅查询请求量增加的场景中,通过主从架构实现读写分离能够满足业务读多写少的需求,从而保证系统的可靠性。然而,当数据库中单表数据量增大时,业务操作的耗时会增加。有时,由于业务特点的限制,归档或删除操作无法从根本上解决问题。此外,进行大表结构变更时需要拷贝数据,若表数据量过大会导致无剩余空间进行表结构修改。

当单表数据量过大或写操作负荷过高,以至于达到存储或性能的上限时,必须通过数据切分等方式进行治理。核心思想是通过分割数据,确保单表和单机的负荷在机器性能许可的范围内。


2、切分方案有哪些?

切分方案主要解决的问题
只分库不分表(分库)数据库读/写QPS过高,数据库连接数不足
只分表不分库(分表)单表数据量过大,存储性能遇到瓶颈
既分库又分表(分库分表)以上两种问题

2.1 分库

分库,指的是将数据从单个数据库拆分成多个数据库的过程。拆分后的数据库往往部署在多套集群中,这也就意味着降低了单个集群的负载压力,提升整体的读写性能。

分库通常有两种方式,垂直分库和水平分库。

2.1.1 垂直分库

垂直分库是指根据业务领域划分,将不同领域的库表拆分到多个数据库中,从而分散数据存储和读取压力,降低数据层面的耦合度。

垂直分库

2.1.2 水平分库

水平分库通常与分表操作一起进行。当单表数据量过大,导致存储容量和读写性能出现瓶颈时,可以根据一定规则将单表拆分成多个表,并将这些表存储在不同的数据库中,从而解决存储容量和性能问题。
水平分库


2.2 分表

分表,指的是将单张数据表拆分成多张表的过程,以减少单表容量,提升读写效率。如提升数据写入时索引的构建效率、减少锁范围等;对于读流量也能较好减少耗时。

分表通常有两种方式:垂直分表和水平分表。

2.2.1 垂直分表

垂直分表是指根据实际应用场景,将数据表中的部分列拆分出来,改变原有表结构。通常可以结合实际查询需求、冷热数据分离和大字段独立存储等方式进行分表。如将db库中的订单表拆分为订单基本信息表和订单详细信息表。
垂直分表

2.2.2 水平分表

水平分表是指当单表数据量过大且不断增长,导致存储备份缓慢和读取效率低下时,将单表按一定规则拆分成多张表。这样可以降低单表容量,提升数据查询效率。如将db库中的订单表拆分为32个分表,order_[0-31],分表还位于同一个库中。
水平分表

2.3 分库分表

在处理海量数据时,单一的数据库和数据表会面临存储容量和性能瓶颈。通过同时进行分库和分表,我们可以将单表的数据水平拆分为多个表,并将这些表分散存储在多个数据库中。这样不仅能有效降低单一数据库和数据表的负载压力,还能提升数据的读写性能和系统的整体稳定性。


3、数据水平分片方法

确定了分库分表后就需要考虑如何将数据分到哪个库或哪个表中。分片是一种水平切分数据表的方式,可以将数据按特定策略切分成多个数据文件,这些文件既可以存储在单节点上,也可以存储在分布式的多个节点上,从而实现更强大的存储和计算能力。下面介绍几种常见的数据分片方法。

3.1 Hash分片

Hash分片,就是按照数据记录中指定关键字的Hash值将数据记录映射到不同的分片中。如图所示,通过一个Hash函数计算用户ID的Hash值而后取模,分配到对应的分片。模为4的原因是系统一共有四个节点,每个节点作为一个分片。

hash分片
优点:这种方法实现简洁,可以保证数据非常均匀地分布到多个分片上。
缺点:直接用节点数作为模,如果系统节点数量变动,模也随之改变,数据就要重新Hash计算,从而带来大规模的数据迁移。显然,这种方式的扩展性不好。

必须找一个方法提升系统的扩展性,就是接下来要介绍的一致性Hash。

3.2 一致性Hash分片

一致性哈希是一种特殊的哈希算法,其核心思想是在一个虚拟的环上分布数据和节点,不同于传统的哈希算法,这种方法在增加或删除节点时能够最小化数据重分布。

如图所示,首先会引入虚拟节点,每个虚拟节点就是一个分片。这个案例中将分片数量设定为16。(因为分片数量决定了集群的最大规模,所以实践中它通常会远大于初始集群节点数。)

一致性Hash
16个分片构成了整个Hash空间,数据记录都要通过Hash函数映射到这个空间,我们换一种方式画图,可以看得更清楚些。如下图所示,Hash空间构成了一个Hash环,数据按照顺时针找到最近的节点。
hash环

当我们新增一台服务器,即节点E时,受影响的数据仅仅是新服务器到其环空间中前一台服务器(即沿着逆时针方向的第一台服务器)之间数据。结合我们的示例,只有小红分享的消息从节点B被移动到节点E,其他节点的数据保持不变。此后,节点B只存储Hash值6和7的消息,节点E存储Hash值4和5的消息。
hash环加节点
一致性哈希优点:

  • 数据均衡:能够将数据均衡地分布到多个表中,避免某些表过度负载。
  • 扩展性强:当需要增加新的表时,一致性哈希允许新的表平滑地加入系统,不会导致大量数据重新分布。部分表失效或移除的情况下,一致性哈希能将其数据分布到剩余的表中,减小影响范围。

3.3 Range分片

范围分片是一种根据数据值的范围将数据拆分成多个部分(片)的分片方法。每个片包含一个特定范围内的连续数据。通常,这种方法使用数据的某个关键字段来确定数据的范围,例如日期、用户ID、订单号等。

假设有一个订单表 orders,我们可以按订单日期将其拆分成不同的分片:

orders_2020: 存储2020年的订单
orders_2021: 存储2021年的订单
orders_2022: 存储2022年的订单

这种方式使用偏少,先介绍到这。工作中MySQL分片最常用的还是Hash分片。


4、分库分表的挑战

4.1 分布式id

在分库分表后,我们不能再使用mysql的自增主键。因为在插入记录的时候,不同的库生成的记录的自增id会出现冲突。因此需要有一个全局的id生成器。

4.2 分布式事务

原本采用单库,通过本地事务就可以保障一致性。分库后因为涉及到了同时更新多个数据库,如何保证要么同时成功,要么同时失败。分布式事务是分库分表绕不过去的一个坎。柔性事务是目前比较主流的方案,柔性事务包括:最大努力通知型、可靠消息最终一致性方案以及TCC两阶段提交等。

4.3 动态扩容

动态扩容指的是增加分库分表的数量。例如原来的user表拆分到2个库的4张表上。现在我们希望将分库的数量变为4个,分表的数量变为8个。这种情况下一般要伴随着数据迁移。

4.4 跨库关联问题

单库下的表连接操作,在分库后需要进行改造。常见的方式有冗余存储数据、应用层拼接等;

4.5 服务、数据平滑迁移

单库单表迁移到分库分表后,为了保证平稳过渡,上层无影响,需要采用相应的策略进行服务、数据的迁移;

4.6 数据库基本的增删改功能

对于开发人员而言,虽然分库分表,但还是希望能和单库单表那样的去简单地操作数据库,包括查询与DML操作。(通常是通过数据库中间件实现,中间件的原理大体分为:数据源代理、数据库代理。具体可搜索cobar、zebra、sharding-jdbc等关键字了解其原理)

4.7 子表分库分表

在进行主表分库分表时,子表也需要进行相应的处理。需要按照相同的分片规则进行分库分表,确保数据的关联性和查询的效率。工作量会翻倍。


5、项目实战

XXXXXXXXXXXXXXXXXXX 待补充XXXXXX

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

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

相关文章

LLM:归一化 总结

一、Batch Normalization 原理 Batch Normalization 是一种用于加速神经网络训练并提高稳定性的技术。它通过在每一层网络的激活值上进行归一化处理,使得每一层的输入分布更加稳定,从而加速训练过程,并且减轻了对参数初始化的依赖。 公式 …

分类模型——逻辑回归和Fisher线性判别分析

个人学习笔记,课程为数学建模清风付费课程 目录 一、引例 二、逻辑回归 2.1线性概率模型 2.2Fisher线性判别分析 2.3两点分布(伯努利分布) 2.4连接函数的取法 2.5如何求解 2.6如何用于分类 三、SPSS 3.1二元分类 3.1.1逻辑回…

MySQL内如何改变编码格式

查找数据库的编码格式&#xff1a; show variables like character%;具体内容时这些 在创建表时设定编码格式&#xff1a; create database <要创建的数据库的名字> charset utf8; 修改数据库默认编码&#xff1a; set character_set_databaseutf8mb4; character_…

eclipse ui bug

eclipse ui bug界面缺陷&#xff0c;可能项目过多&#xff0c;特别maven项目过多&#xff0c;下载&#xff0c;自动编译&#xff0c;加载更新界面异常 所有窗口死活Restore不回去了 1&#xff09;尝试创建项目&#xff0c;还原界面&#xff0c;失败 2&#xff09;关闭所有窗口&…

将TP5链接导入笔影个人博客代码

首先第一步&#xff0c;打开界面 第二步&#xff0c;这里卡住了&#xff0c;无法看到源代码&#xff0c;我们使用其他软件看看源代码 调试乱码&#xff0c;因为没有找到相应的笔影个人博客源码。源码在桌面上。询问百度&#xff0c;说了有的没的一大堆。 尝试的结果就是失败…

时间复杂度与O(n)

文章目录 1 复杂度分析1.1 时间复杂度1.1.1 循环执行次数1.1.2 大O(n)表示法 1.2 空间复杂度 1 复杂度分析 1.1 时间复杂度 ​ 时间复杂度用来表示算法运行时间的长短&#xff0c;用来定性的描述程序的运行时间。要了解时间复杂度&#xff0c;我们需要先了解程序执行的次数。…

机器学习(二十二):精度和召回率

一、倾斜数据集 倾斜数据集&#xff1a;一个数据集中的正面和负面例子的比例非常不平衡&#xff0c;比如数据集中&#xff0c;结果为1的占比20%&#xff0c;结果为0的占比80% 例子&#xff1a;如果数据集的结果中只有0.5%是1&#xff0c;其余结果是0。有一个模型的预测准确度…

【信创】udisk2服务异常导致U盘使用中自动移除问题解决

原文链接&#xff1a;【信创】udisk2服务异常导致U盘使用中自动移除问题解决 Hello&#xff0c;大家好啊&#xff01;今天给大家带来一篇关于在信创终端操作系统上由于udisk2服务异常导致U盘等移动设备在使用中自动移除问题的排查文章。udisk2是一个管理存储设备的服务&#xf…

【计算机网络】OSPF单区域实验

一&#xff1a;实验目的 1&#xff1a;掌握在路由器上配置OSPF单区域。 2&#xff1a;学习OSPF协议的原理&#xff0c;及其网络拓扑结构改变后的变化。 二&#xff1a;实验仪器设备及软件 硬件&#xff1a;RCMS交换机、网线、内网网卡接口、Windows 2019操作系统的计算机等。…

Vue 3 实现左侧列表点击跳转滚动到右侧对应区域的功能

使用 Vue 3 实现左侧列表点击跳转到右侧对应区域的功能 1. 引言 在这篇博客中&#xff0c;我们将展示如何使用 Vue 3 实现一个简单的页面布局&#xff0c;其中左侧是一个列表&#xff0c;点击列表项时&#xff0c;右侧会平滑滚动到对应的内容区域。这种布局在很多应用场景中都…

Llama 3.1 405B 详解

2024 年 7 月 23 日星期二&#xff0c;Meta 宣布推出 Llama 3.1&#xff0c;这是其Llama 系列大型语言模型 (LLM)的最新版本。虽然只是对 Llama 3 模型进行小幅更新&#xff0c;但它特别引入了Llama 3.1 405B——一个 4050 亿参数的模型&#xff0c;这是迄今为止世界上最大的开…

运行ruoyi

nacos 数据库配置 修改nacos/conf/application.properties 单机版运行 startup.cmd -m standalone redis 运行后端 运行gateway,auth,modules/system模块 可能遇到的问题&#xff1a;端口正在使用 解决 netstat -ano | findstr 9200 taskkill -pid 18284 -f

JAVA同城圈子达人交友系统源码支持微信小程序+公众号+H5+APP

&#x1f308; 同城圈子达人交友系统&#xff0c;遇见志同道合的TA&#xff01; &#x1f389; 开篇&#xff1a;告别孤单&#xff0c;同城圈子等你来探索&#xff01; 在这个快节奏的城市生活中&#xff0c;你是否常常感到孤独&#xff0c;渴望找到一群志同道合的朋友&#…

Elasticsearch基础(六):使用Kibana Lens进行数据可视化

文章目录 使用Kibana Lens进行数据可视化 一、进入Kibana Lens 二、基础可视化 1、指标可视化 2、垂直堆积条形图 3、表格 三、高级可视化 1、多图层和索引 2、子桶 3、树状图 使用Kibana Lens进行数据可视化 一、进入Kibana Lens 在Kibana主页&#xff0c;单击页面…

【资料分享】2024钉钉杯大数据挑战赛A题思路解析+代码演示

2024第三届钉钉杯大学生大数据挑战赛今天已经开赛&#xff0c;【A题】思路解析代码&#xff0c;资料预览&#xff1a;

【JAVA学习笔记】找不到依赖项 ‘org.springframework.boot:spring-boot-starter-web:3.0.5‘

如果环境都是跟着教程配的话&#xff0c;并且上网搜了一圈询问gpt都没发现对应长得像的错误&#xff0c;那么试试**刷新一下Maven项目**&#xff0c;可能问题就自己解决了。如果这样解决不了再查到底是什么地方没有配置对。&#xff08;我第一次遇到这个问题的时候搜了半天都不…

遇到 chunk of umi not found 处理办法

1、删除 以下文件 &#xff08;1&#xff09;node_modules 其中快速删除node_modules方法可参考&#xff1a;rimraf快速删除node_modules方法-CSDN博客文章浏览阅读258次。rimraf快速删除node_modules方法https://blog.csdn.net/2401_85955297/article/details/140566245?spm…

微信小游戏之 三消(一)

首先设定一下 单个 方块 cell 类&#xff1a; 类定义和属性 init 方法 用于初始化方块&#xff0c;接收游戏实例、数据、宽度、道具类型和位置。 onWarning 方法 设置警告精灵的帧&#xff0c;并播放闪烁动作&#xff0c;用于显示方块的警告状态。 grow 方法 根据传入的方向…

网络基础之(11)优秀学习资料

网络基础之(11)优秀学习资料 Author&#xff1a;Once Day Date: 2024年7月27日 漫漫长路&#xff0c;有人对你笑过嘛… 全系列文档可参考专栏&#xff1a;通信网络技术_Once-Day的博客-CSDN博客。 参考文档&#xff1a; 网络工程初学者的学习方法及成长之路&#xff08;红…

【视频讲解】后端增删改查接口有什么用?

B站视频地址 B站视频地址 前言 “后端增删改查接口有什么用”&#xff0c;其实这句话可以拆解为下面3个问题。 接口是什么意思&#xff1f;后端接口是什么意思&#xff1f;后端接口中的增删改查接口有什么用&#xff1f; 1、接口 概念&#xff1a;接口的概念在不同的领域中…