什么是分库分表?代表性框架有哪些?

news2024/11/27 19:45:57

在互联网系统开发过程中,所谓的分库分表并不是一个新概念。或者说,对于很多开发人员而言,说起分库分表,大家都或多或少有所了解,也都知道数据量大了就需要进行分库分表。但是究竟如何实现分库分表呢?

要想回答“如何让分库分表真正落地?”这个问题,我们先从一个典型的案例说起。试想在一个电商系统中,势必存在订单表。系统在初始运行期间,我们一般使用单库和单表的方式来存储和访问数据。因为数据量不大,所以数据库访问的瓶颈并不明显。

随着业务的演进,当需要支撑大规模电商业务时,系统每天可能会生成数十万甚至百万级别的订单数据。随着数据量越来越大,订单表的访问就会出现瓶颈。

以互联网系统中常用的MySQL数据库为例,虽然单表可以存储的数据原则上可以达到亿条级别,但这时候访问性能就会变得很差。即使采用各种调优策略,通常效果也微乎其微。业界普遍认为,MySQL单表容量在1千万以下是一种最佳状态,一旦超过这个量级,就需要考虑采用其他方案。

既然以MySQL为代表的关系型数据库中的单表无法支持大数据量存储和访问方案,我们自然而言可能想到是否可以采用诸如MongoDB等NoSQL的方式来管理数据呢?我们认为这并不是一个很好的选项。原因有很多,一方面关系型生态系统非常完善,关系型数据库经过几十年的持续发展,具有NoSQL所无法比拟的稳定性和可靠性。同时,关系型数据库的事务特性也是其他数据存储工具所不具备的一项核心功能。目前绝大部分公司的核心数据都是存储在关系型数据库中,就互联网公司而言,MySQL是主流的数据存储方案。

现在,我们选择了关系型数据库,那么就可以考虑采用分库分表的方案来解决单表瓶颈问题,这是目前互联网行业处理海量数据的通用方法。分库分表方案更多的是对关系型数据库数据存储和访问机制的一种补充,而不是颠覆。那么究竟什么是分库分表呢?

什么是数据分库分表?

分库和分表是两个概念,但通常我们会把它们合在一起简称为分库分表。所谓分库分表,业界并没有一个统一的定义,我们可以简单理解为:为了解决由于数据量过大而导致数据库性能降低的问题,将原来独立的数据库拆分成若干数据库,将原来数据量大的表拆分成若干数据表组成,使得单一数据库、单一数据表的数据量变得足够小,从而达到提升数据库性能的效果。分库分表的表现形式也有很多种,我们来看一下。

分库分表包括分库和分表两个维度,在开发过程中,对于每个维度都可以采用两种拆分思路,即垂直拆分和水平拆分,如下图所示:


我们先来讨论垂直拆分的应用方式,相比水平拆分,垂直拆分相对比较容易理解和实现。在电商系统中,用户在打开首页时,往往会加载一些用户的性别、地理位置等基础数据。对于用户表而言,这些位于首页的基础数据显然访问频率要比那些用户的头像等数据更高。基于这两种数据的不同访问特性,我们可以把用户单表进行拆分,将访问频次低的用户头像等信息单独存放在一张表中,访问频次较高的用户信息单独放在另一张表中,如下所示:


由此可以,垂直分表的处理方式就是将一个表按照字段分成多表,每个表存储其中一部分字段。在实现上,我们通常会把头像等blob类型的大字段数据或热度较低的数据放在一张独立的表中。将经常需要组合查询的列放在一张表中也可以认为是分表操作的一种表现形式。

通过垂直分表能得到来一定程度的性能提升,但毕竟数据仍然位于同一个数据库中,也就将操作范围限制在一台服务器,每个表还是会竞争同一台服务器中的CPU、内存、网络IO等资源。基于这一考虑,在有了垂直分表之后,我们就可以进一步引入垂直分库。

对于前面介绍的场景,分表之后的用户信息同样还是跟其他的商品、订单信息存放在同一台服务器中。基于垂直分库思想,这时候,我们就可以把用户相关的数据表单独拆分出来,放在一个独立的数据库中,如下图所示:


上图的效果就是垂直分库。从定义上讲,垂直分库是指按照业务将表进行分类,然后分布到不同的数据库上。然后,每个库可以位于不同的服务器上,其核心理念是专库专用。而从实现上讲,垂直分库的实现很大程度上取决于业务的规划和系统边界的划分。比如说,用户数据的独立拆分就需要考虑到系统用户体系与其他业务模块之间的关联关系,而不是说简单的创建一个用户库即可。在高并发场景下,垂直分库能够一定程度的提升IO访问效率和数据库连接数,并降低单机硬件资源的瓶颈。

从前面的分析中我们不难明白,垂直拆分尽管实现起来比较简单,但并不能解决单表数据量过大这一核心问题。所以,现实中我们往往需要在垂直拆分的基础上添加水平拆分机制。例如,我们可以对用户库中的用户信息按照用户ID进行取模,然后分别存储在不同的数据库中,这就是水平分库的常见做法,如下所示:


可以看到,水平分库是把同一个表的数据按一定规则拆分到不同的数据库中,每个库同样可以位于不同的服务器上。这种方案往往能解决单库存储量及性能瓶颈,但由于同一个表被分配在不同的数据库,数据的访问需要额外的路由工作,因此大大提升了系统复杂度。这里所谓的规则实际上就是一系列的算法,常见的包括:

  1. 取模算法

取模的方式有很多,例如前面介绍的按照用户ID进行取模,当然也可以通过表的一列字段进行hash求值来进行取模

  1. 范围限定算法

范围限定也很常见,例如我们可以采用按年份、按时间等策略路由到目标数据库或表

  1. 预定义算法

所谓预定义,就是指事先规划好具体库或表的数量,然后直接路由到指定库或表中

按照水平分库的思路,我们也可以对用户库中的用户表进行水平拆分,效果如下所示。也就是说,水平分表是在同一个数据库内,把同一个表的数据按一定规则拆到多个表中。


显然,系统的数据存储架构演变到现在已经非常复杂了。与拆分前的单库单表相比,现在我们面临着一系列具有挑战性的问题,例如:

  1. 如何对多数据库进行高效治理?
  2. 如何进行跨节点关联查询?
  3. 如何实现跨节点的分页和排序操作?
  4. 如何生成全局唯一的主键?
  5. 如何确保事务一致性?
  6. 如何对数据进行迁移等?

如果没有很好的工具来支持数据的存储和访问,那么数据一致性将很难得到保障,这就是各种分库分表开发框架的价值所在。

分库分表解决方案和代表框架

基于前面关于分库分表的讨论,我们可以抽象其背后的一个核心概念,这个概念就是分片(Sharding),即无论是分库还是分表,都是把数据划分成不同的数据片,并存储在不同的目标对象中。而具体的分片方式就涉及到实现分库分表的不同解决方案。

如果要列举业界关于分库分表的框架,我们发现实际上也有不少。这些框架显然并不是采用同一种解决方案。但通过分析这些框架在实现数据分片方案上的区别,我们也可以把它们分成三大类型,即客户端分片、代码服务器分片以及分布式数据库。

客户端分片

所谓客户端分片,相当于在在数据库的客户端就完成了分片规则的实现。显然,这种方式将分片管理的工作进行前置,客户端管理和维护着所有的分片逻辑,并决定每次SQL执行所对应的目标数据库和数据表。

客户端分片这一解决方案也有不同的表现形式,其中最为简单的方式就是应用层分片,也就是说在应用程序中直接维护着分片信息,效果如下图所示:


在具体实现上,我们通常会将分片规则的处理逻辑打包成一个公共JAR包,其他业务开发人员只需要在代码工程中引入这个JAR包即可。针对这种方案,因为没有独立的服务器组件,所以也不需要专门维护某一个具体的中间件。然而,这种直接在业务代码中嵌入分片组件的方法也有明显的缺点。一方面,因为分片逻辑侵入到了业务代码中,业务开发人员在理解业务的基础上还需要掌握分片规则的处理方式,增加了开发和维护成本。而且,一旦出现问题,也只能依赖业务开发人员通过分析代码来找到原因,而无法把这部分工作抽离出来让专门的中间件团队进行完成。

基于以上分析,客户端分片在实现上通常会进行进一步的抽象,把分片规则的管理工作从业务代码中剥离出来形成单独演进的一套体系。一种思路是重写JDBC协议,也就是说在JDBC协议层面嵌入分片规则。这样,业务开发人员还是使用与JDBC规范完全兼容的一套API来操作数据库,但这套API的背后却自动完成了分片操作,从而实现对业务代码的零侵入,效果如下:


这种解决方案的优势在于分片操作对于业务而言是完全透明的,从而一定程度上实现业务开发人员与数据库中间件团队在职责上的分离。这样,业务开发人员只需要理解JDBC规范就可以完成分库分表,开发难度以及代码维护成本得到降低。

对于客户端分片,典型的中间件包括阿里巴巴的TDDL以及Apache顶级项目ShardingSphere。因为TDDL并没有开源,所以我们无法判断其使用了哪种客户端分片方案。而对于ShardingSphere而言,它是重写JDBC规范以实现客户端分片的典型实现框架。

代理服务器分片

代理服务器分片的解决方案也比较明确,顾名思义,就是采用了代理机制,也就是说在应用层和数据库层之间添加一个代理层。有了代理层之后,我们就可以把分片规则集中维护在这个代理层中,并对外提供与JDBC兼容的API给到应用层。这样,应用层的业务开发人员就不用关心具体的分片规则,而只需要完成业务逻辑的实现,其效果如下所示:


显然,代理服务器分片的优点在于解放了业务开发人员对分片规则的管理工作,而缺点就是添加了一层代理层,所以天生具有代理所带来的一些问题,比方说因为新增了一层网络传输对性能所产生的影响。

对于代理服务器分片,常见的开源框架有阿里的Cobar以及民间开源社区的Mycat。而在ShardingSphere中,也添加了Sharding-Proxy模块来实现代理服务器分片。

分布式数据库 

在技术发展和演进的过程中,关系型数据库的一大问题在于缺乏分布式特性,也就说缺乏分布式环境下面对大数量、高并发访问的有效数据处理机制。举例来说,我们知道事务是关系型数据库的本质特征之一,但在分布式环境下,如果我们想要基于MySQL等传统关系型数据库来实现事务将面临巨大的挑战。

幸好,以TiDB为代表的分布式数据库的兴起赋予了关系型数据库一定程度的分布式特性。在这些分布式数据库中,数据分片以及分布式事务将是其内置的基础功能,对业务开发人员是透明的。业务开发人员只需要使用TiDB对外提供的JDBC接口,就像在使用MySQL等传统关系型数据库一样。

从这个角度讲,我们也可以认为ShardingSphere是一种分布式数据库中间件。它在提供标准化的数据分片解决方案之外,也实现了分布式事务和数据库治理功能。

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

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

相关文章

去哪个网站找视频素材?哪里有视频素材不侵权?

在这个视觉内容日益丰富的时代,掌握优质的视频素材资源成了每位创作者的必备技能。高清、4K视频素材在制作中扮演着至关重要的角色,它们不仅提升了视觉效果,更增强了观众的沉浸感。下面将为您介绍几个全球知名的视频素材网站。 1. 蛙学府 提…

企业内外网隔离后的文件传输解决方案

一、企业为什么要进行内外网隔离 在当今信息化快速发展的时代,企业内部网络的构建和管理显得尤为重要。为了更好地保护企业信息安全和提高工作效率,许多企业选择将网络划分为内网和外网。那么,企业划分内外网的作用具体体现在哪些方面呢&…

从古代故事中领悟高情商回话

页面 页面代码 <% layout(/layouts/default.html, {title: 故事管理, libs: [dataGrid]}){ %> <div class"main-content"><div class"box box-main"><div class"box-header"><div class"box-title">&l…

【Django项目】 通过AI实现视频转文字

使用Django构建一个视频—>文字 转换器&#xff1a; 输入视频地址&#xff0c;通过OpenAI的接口分析视频&#xff0c;返回视频内容的文字。 视频 代码 运行此程序&#xff0c;需要OpenAI-key和设置Postgres数据库。 &#xff08;吐槽一下&#xff0c;作者把这些信息都直接写…

vue路由知识补充(updating···)

1路由守卫中的next() next()方法表示放行&#xff0c;如果不执行此方法路由不会跳转&#xff0c;此方法可以接收一个参数 字符串路径&#xff1a;如果传递一个字符串路径&#xff0c;那么路由会重定向到该路径。 next(/home); 路由对象&#xff1a;如果传递一个路由对象&…

搜维尔科技:光学动作捕捉系统用于城市公共安全智慧感知实验室

用户名称&#xff1a;西安科技大学 主要产品&#xff1a;Optitrack Priime41 光学动作捕捉系统&#xff08;8头&#xff09; 在6米8米的空间内&#xff0c;通过8个Optitrack Priime41光学动作捕捉镜头&#xff0c;对人体动作进行捕捉&#xff0c;得到用户想要的人体三维空间坐…

安卓手机平板使用Termux+Hexo搭建本地博客站点并实现无公网IP远程访问

文章目录 前言1.安装 Hexo2.安装cpolar3.远程访问4.固定公网地址 前言 本文主要介绍如何在安卓手机平板Termux中安装个人hexo博客并结合cpolar内网穿透工具&#xff0c;实现远程访问本地搭建的博客站点&#xff0c;无需公网IP。 Hexo 是一个用 Nodejs 编写的快速、简洁且高效…

Linux的并发与竞争

文章目录 一、并发二、竞争三、保护内容是什么四、解决并发与竞争的几种常用方法1.原子操作原子整型API函数原子位操作 API 函数 2.自旋锁自旋锁格式如下&#xff1a;自旋锁 API 函数自旋锁的使用注意事项 3.信号量信号量 API 函数信号量格式如下&#xff1a; 4.互斥体API函数如…

面试算法之哈希专题

赎金信 class Solution { public:bool canConstruct(string ransomNote, string magazine) {// 小写字母int r_cnt[26];int m_cnt[26];for(int i 0; i< magazine.size(); i) {m_cnt[magazine[i]-a]; // 统计}// 对比for(int i 0; i< ransomNote.size(); i) {if(m_cnt[r…

Python-----容器的介绍以及操作

1.列表和元组 1.列表是什么, 元组是什么&#xff1a; 编程中, 经常需要使用变量, 来保存/表示数据. 如果代码中需要表示的数据个数比较少, 我们直接创建多个变量即可. 但是有的时候, 代码中需要表示的数据特别多, 甚至也不知道要表示多少个数据. 这个时候, 就需要用到列表 列表…

ChatGPT开源的whisper音频生成字幕

1、前言 好了&#xff0c;那接下来看一下whisper开源库的介绍 有五种模型大小&#xff0c;其中四种仅支持英语&#xff0c;提供速度和准确性的权衡。上面便是可用模型的名称、大致的内存需求和相对速度。如果是英文版的语音&#xff0c;直接想转换为英文。 本来我是想直接在我的…

数据库(MySQL)基础:约束

一、概述 1.概念&#xff1a;约束是作用于表中字段上的规则&#xff0c;用于限制存储在表中的数据。 2.目的&#xff1a;保证数据库中数据的正确、有效性和完整性。 3.分类 约束描述关键字非空约束限制该字段的数据不能为nullnot null唯一约束保证该字段的所有数据都是唯一…

粮油码垛机:自动化与智能化仓储的关键角色

在快速发展的现代化仓储物流领域&#xff0c;粮油码垛机正逐渐成为自动化与智能化仓储的关键角色。它以其高效、精准、节省人力的特点&#xff0c;赢得了众多粮油生产企业的青睐&#xff0c;成为仓储管理升级换代的明星产品。 一、粮油码垛机的技术革新 随着科技的发展&#…

欧洲杯/奥运会-云直播

欧洲杯/奥运会要来了&#xff0c;如何升级自己的网站让你的顾客都能观赏直播已提高用户量呢&#xff1f;&#xff01; 【功能完善、平滑兼容】 云直播支持 RTMP 推流、 HLS 源站等多种直播源接入方式&#xff0c;提供直播 SDK&#xff0c;支持多终端适配&#xff0c;上行码率…

DDD架构理论详解

文章目录 一、概念入门1. 概念简介2. DDD的核心理念3. 范式4. 模型5. 框架6. 方法论7. 软件设计的主要活动 二、DDD核心理论1. Domain领域层都包含什么&#xff1f;2. 聚合、实体和值对象3. 仓储&#xff0c;封装持久化数据4. 适配&#xff08;端口&#xff09;&#xff0c;调用…

音频系统模块级实验

加zkhengyang进数字音频系统研究开发交流答疑群(课题组) 1 购买ADC-I2S模块&#xff0c;购买I2S-DAC模块 进行音频系统搭建&#xff0c;可加深对i2s音频总线的理解 2 用电脑的音频输出进行实验

邊緣智能2024—AI開發者峰會(5月9日)數碼港即將啟幕

隨著 AI &#xff08;人工智能&#xff09;技術的飛速發展&#xff0c;我們正迎來邊緣計算智能化與分布式AI深度融合的新時代&#xff0c;共同演繹分布式智能創新應用的壯麗篇章。"邊緣智能2024 - AI開發者峰會"將聚焦於這一前沿領域&#xff0c;探討如何通過邊緣計算…

大模型LLM之SFT微调总结

一. SFT微调是什么 在大模型的加持下现有的语义理解系统的效果有一个质的飞跃&#xff1b;相对于之前的有监督的Pre-Train模型&#xff1b;大模型在某些特定的任务中碾压式的超过传统nlp效果&#xff1b;由于常见的大模型参数量巨大&#xff1b;在实际工作中很难直接对大模型训…

树莓派 CM4S - 计算模块系列的新内存变体

自 2014 年以来&#xff0c;我们专门为工业和嵌入式应用设计提供 Raspberry Pi 的强大功能&#xff0c;我们惊讶并欣喜地看到客户使用 Raspberry Pi 计算模块的方式变得多种多样。我们很高兴地宣布&#xff0c;我们已经扩展了 Compute Module 4S 产品&#xff1a;这些工业板现在…

uniapp开发小程序---文章转发分享问题

一、需求 标题这里有三个新闻分类&#xff08;跳转的列表页是同一个&#xff0c;是根据分类字段来判断显示的&#xff09;&#xff1a; 在列表页面点击右上角分享给好友后是下图所示&#xff1a; 要求点击每个分享过来的页面时&#xff0c;跳转到对应的新闻列表下。 二、代码…