深入理解MySQL——分库分表种类与原则

news2024/11/26 0:38:50

分库分表的种类

首先说明,这里所说的分库分表是指把数据库中数据物理地拆分到多个实例或多台机器上去,而不是MySQL原生的Partitioning。

这里稍微提一下Partitioning,这是MySQL官方版本支持的,在本地针对表的分区进行操作,它可以将一张表的数据分别存储为多个文件。

如果在写SQL的时候,遵从了分区规则,就能把原本需要遍历全表的工作转变为只需要遍历表里某一个或某些分区的工作。

这样降低了查询对服务器的压力,提升了查询效率。如果分区表使用得当,也可能大规模地提升MySQL 的服务能力。

但是这种分区方式,一方面,在使用的时候必须遵从分区规则写SQL语句,如果不符合分区规则,性能反而会非常低下;

另一方面,Partitioning的结果受到MySQL实例,或者说MySQL单实例的数据文件无法分布式存储的限制,不管怎么分区,所有的数据还是都在一个服务器上,没办法通过水平扩展物理服务的方法把压力分摊出去。所以,限于篇幅,在讲分库分表时就不谈Partitioning这种分区方式了。

在MySQL运维实践中,拆分一般分为垂直拆分和水平拆分。

垂直拆分

在考虑数据库拆分的时候,一般情况下,应该先考虑垂直拆分。垂直可以理解为分出来的库表结构是互相独立各不相同的。

如果有多个业务,每个业务直接关联性不大,那么就可以把每个业务拆分为单独的实例、库或表。

如果在一个实例上,有多个数据库,那么从分摊压力的角度考虑,可以把每个数据库拆分到单独的实例上。

如果在一个库里面有多张表,那么可以把每张表拆分到不同的实例上。

如果你有一张表,但这个表里的字段很多,每个字段都有不同的含义,例如user表里面有姓名、生日、地址等个人信息,那么当改表太大的时候,就可以把每个字段独立出来拆分为一张新表。例如user_birth表,可以只有两个字段:user_id、user_birthday。

水平拆分

水平拆分是针对一张表来说的。在经过垂直拆分之后,如果数据量仍然过大,例如注册用户已经超过了10亿,那只好通过某种算法进行水平拆分。拆分后的结果是多张具有相同表结构的表,每张表里面存储一部分数据。拆分的算法依据很多,例如通过id取模100、1024的方式,以及通过区分不同日期的方式等,如图24.1所示。

blog表通过取模100,分成了100份。log表通过每个月一个表进行按时间的水平拆分。feed表通过除以约定的值进行了水平拆分。

在这里插入图片描述
此外,还有一种拆分方式是水平拆分之后的垂直拆分。

进行拆分的目的是,通过这样的做法降低MySQL的负载,把原本不支持分布式存储的MySQL实例转换为基于MySQL的分布式集群。在进行水平拆分之后,如果数据库压力还是非常大,那么可以把水平拆分的结果再进行垂直拆分。

例如上面的blog表。先通过水平拆分把一张blog表拆分为100份;然后,可以根据业务的需求,再通过垂直拆分,把一部分水平拆分后的blog_N表迁移出去。按照目前的设计,在极端情况下,可以把blog表分布在100台物理机器上,每台物理机器上承担blog表访问压力的百分之一。

这样的操作在MySQL Partitioning中是无法完成的。

此外,还有一种拆分方式是水平拆分之后的垂直拆分。
进行拆分的目的是,通过这样的做法降低MySQL的负载,把原本不支持分布式存储的MySQL实例转换为基于MySQL的分布式集群。在进行水平拆分之后,如果数据库压力还是非常大,那么可以把水平拆分的结果再进行垂直拆分。

例如上面的blog表。先通过水平拆分把一张blog表拆分为100份;然后,可以根据业务的需求,再通过垂直拆分,把一部分水平拆分后的blog_N表迁移出去。按照目前的设计,在极端情况下,可以把blog表分布在100台物理机器上,每台物理机器上承担blog表访问压力的百分之一。

这样的操作在MySQL Partitioning中是无法完成的。

分库分表的原则

从一般运维的角度来看,什么情况下需要考虑分库分表呢?

原则零:能不分就不分。

MySQL是关系型数据库,数据库表之间的关系从一定的角度上映射了业务逻辑。

任何分库分表的行为都会在某种程度上提升业务逻辑的复杂度,数据库除了承载数据的存储和访问外,协助业务更好地实现需求和逻辑也是其重要工作之一。

分库分表会带来数据的合并、查询或更新条件的分离,以及事务的分离等多种后果,业务实现的复杂程度往往会翻倍或指数级上升。所以,在分库分表之前,不要为分而分,而应该尽量去做其他力所能及的事情,例如升级硬盘、升级内存、升级CPU、升级网络、升级数据库版本、读写分离及负载均衡等。所有分库分表的前提是,这些已经尽力做好了。

原则一:数据量太大,正常的运维影响正常的业务访问。

这里说的运维,包括如下三种情况。

    1. 对数据库的备份。

如果单表或单个实例太大,在做备份的时候就需要大量的磁盘IO或网络IO资源。例如1T的数据,网络传输占用50MB的时候,需要20000多秒才能传输完毕,整个过程中的维护风险都是高于平时的。

去哪儿网的做法是,给所有的数据库机器添加第二块网卡,用来做备份,或者SST、Group Communication等各种内部的数据传输。lT的数据备份,也会占用大量的磁盘IO,如果是SSD还好。

当然,这里忽略某些厂商的产品在集中IO的时候会出一些BUG的问题。如果是普通的物理磁盘,则在不限流的情况下去执行XtraBackup,但对于该实例来说基本不可用。

    1. 对数据表的修改。

如果某个表过大,对此表做DDL的时候,MySQL会锁住全表,这个时间可能会很长,在这段时间内业务不能访问此表,影响甚大。解决的办法有类似某些大厂DBA自己改造的可以在线秒改表的方法,不过他们目前也只是能添加字段而已,对其他DDL还是无效;

或者使用pt-online-schema-change,当然在使用过程中,它需要建立触发器和影子表,同时也需要很长很长的时间,在此操作过程中的所有时间,都可以看作风险时间。

把数据表切分,使总量减小,有助于改善这种风险。

    1. 整个表的热点数据,数据访问和更新频繁,经常有锁等待。

例如曾经有个表user_last_login_time,从名字可以看出来是记录用户最后一次登录时间信息的表。由于业务开展时的数据量比较小,并且考虑到每个注册用户只有一条记录,就没有分表。

但是随着业务爆发性增长,这张表的数据量很快达到了10亿。这时候,DAU在不到1亿的情况下,就有每天几个亿的update操作(同一个用户可能每天登陆好多次),虽然大部分都是简单的update操作,但由于更新太过频繁,也导致此表压力很大,经常出问题。

这个时候,又没有能力去修改源码,降低锁的粒度,那么只会把其中的数据物理拆开,用空间换时间,变相降低访问压力。这个案例中的热点表拆分,用到了水平拆分。

原则二:表设计不合理,需要对某些字段进行垂直拆分。

这里举一个例子,如果有一个名为users用户表,在最初设计的时候可能是如下这样的。
在这里插入图片描述

一般的users表会有很多字段,这里不再列举。如上表所示,在一个简单的应用中,这种设计是很常见的。但是,设想一下以下两种情况。

  • 设想情况一:你的业务中彩了,用户数从100万飙升到10个亿。

为了统计活跃用户,在每个人登录的时候都会记录一下他最近登录的时间。并且有的用户活跃得很,不断地去更新这个login_time,使这个表不断地被update,压力非常大。

那么,在这个时候,只要考虑对它进行拆分,站在业务的角度,最好的办法是先把last_login_time拆分出去,并将拆分出来的字段命名为user_last_login_time。

这样,业务的代码只有在用到这个字段的时候修改一下就好了。如果不这么做,直接把users表水平切分,那么所有访问users 表的地方都要修改。或许你会说:"我有 proxy,能够动态merge数据。"到目前为止,我还从没看到过proxy不影响性能的情况。

  • 设想情况二:personal_info这个字段本来没什么用,就是让用户注册的时候填一些个人爱好而已,基本不会对它做查询。

一开始的时候,有它没它无所谓。但是后来发现了两个问题,

  1. 这个字段占用了大量的空间,因为是TEXT,所以有很多人喜欢在这里长篇大论地介绍自己;
  2. 更糟糕的是,不知道哪天哪个产品经理心血来潮,说允许个人信息公开吧,以便让大家更好地相互了解。

那么,在所有人猎奇窥私心理的影响下,对此字段的访问量就会大幅度增加。这时,数据库压力瞬间抗不住了,只好考虑对这个表进行垂直拆分。

也就是,把这个字段加上用户的id单独独立出去。关于TEXT的拆分,这里多说一句,如果一个查询表里存在TEXT或BLOB字段,而且这个查询需要创建内部临时表的话,那它不能使用内存临时表,必须使用磁盘临时表,不然会对性能造成巨大影响,也会占用物理磁盘大量IO,最终导致性能剧烈下降。

一般情况下,这是必须要拆分的情形。

原则三:某些数据表出现了无穷增长的情况

例子很好举,各种的评论、消息、日志记录。这个增长不是跟人口成比例的,而是不可控的,例如社交网站业务的feed广播,发一条消息会扩散给很多很多人。虽然主体可能只存一份,但不排除一些索引或路由有这种存储需求。这个时候,通过增加存储提升机器配置已经显得苍白无力,水平切分是最佳实践。拆分的标准很多,按用户的、按时间的、按用途的,不再一一举例。

原则四:安全性和可用性的考虑

这也算是拆分带来的意外惊喜吧。不要把所有鸡蛋放在一个篮子里,我们不希望数据库出问题,但出不出问题不是我们能决定的,或者可以这么说,出问题几乎是一定的。我能决定什么呢?我希望在出问题的时候不要影响到100%的用户,影响的比例越小越好,那么水平切分可以解决这个问题。

把用户、库存、订单等本来统一的资源切分掉,每个小的数据库实例承担一小部分业务,这样整体的可用性就会提升。这对Qunar这样的业务还是比较合适的,人与人之间、某些库存与库存之间关联不太大的时候,可以做一些这样的切分。

原则五:业务耦合性考虑

这一点跟原则四有些类似,主要是站在业务的层面上来看。火车票业务和烤羊腿业务是完全无关的业务,虽然每个业务的数据量可能不太大,放在一个MySQL实例中完全没问题,但是烤羊腿业务的DBA或开发人员水平很可能很差,动不动就给你出一些幺蛾子,直接把数据库搞挂。

这时,虽然火车票业务的人员技术很优秀,工作也很努力,但照样被老板打屁股。解决的办法很简单:惹不起,躲得起!

《三国演义》第一回:"话说天下大势,分久必合,合久必分。"其实在实践中,有时候可能原本要分,后来又发现分了还得合,分分合合,完全是现实的需求,随需而变才是王道,而DBA的价值也能在此体现。或分或合的情况太多,不能穷举。

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

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

相关文章

[Flask]各种子功能的实现

一、标准Flask架构搭建 ①config.py 新建一个文件config.py,在其中进行参数初始化,再使用下面代码加载到app.py(主程序)中 import config app.config.from_object(config) #由config.py初始化 ②exts.py 用于放置扩展模块&a…

(二十四)Vue之props配置项

文章目录props基本使用props的数组形式props的对象形式检测类型检测类型 其他验证Vue学习目录 上一篇:(二十三)Vue之ref属性 props props 可以是数组或对象,用于让组件接收外部传过来的数据 约定props是只读的,Vue…

开源 高性能 云原生!时序数据库 TDengine 上线亚马逊Marketplace

近日,涛思数据旗下开源、高性能、云原生的时序数据库(Time Series Database,TSDB)TDengine 成功上线亚马逊云科技 Marketplace,为用户提供了更加丰富的订阅渠道。 TDengine 是针对时序数据特点研发和优化的数据库解决方…

CentOS8 Elasticsearch8.x 安装遇到的问题解决汇总

报错清单 启动报错:ERROR: Elasticsearch exited unexpectedly curl测试报错:curl: (52) Empty reply from server 报错解决 启动报错 起因 使用archive方式安装elasticsearch后,在目录中运行./bin/elasticsearch报错如下: 原…

第二十七章 数论——快速幂与逆元

第二十七章 快速幂与扩展欧几里德算法一、快速幂1、使用场景2、算法思路(1)二进制优化思想(2)模运算法则3、代码实现(1)问题(2)代码二、快速幂求逆元1、什么是逆元?&…

结构体位段问题

每一位勇敢努力的少年,必将不负众望! 什么是位段 位段的详细解释 位段其实也是一种结构体的类型 1.位段的成员是 int ,short int unsigned int , signed int , short , char 类型 2.位段的成员名后有一个冒号和一个数字 看一个例子: st…

通过静态LSP、LDP LSP、MPLS TE三种方式实现总部与分支的互通

一、静态LSP 特点:类似静态路由,简单易用,手动建立lsp,定制转发路径,无需控制报文,资源消耗少。 缺点:不适合大型复杂拓扑,不能根据网络变化而动态调整,需要管理员手动调…

【jprofiler应用-oom原因定位】

1.安装jprofiler jprofiler_windows-x64_11_0_2.exe 2.使用KeyGen.exe生成注册码然后输入 3.idea中安装jprofiler插件 File-->Setting-->Plugins 搜索jprofiler插件然后安装 4.以一个内存溢出的程序为例子进行分析(一直分配内存,List容器引用着Student导致…

医疗产品设计的新趋势

随着个人健康和医疗数据技术的发展,消费者可以选择更多的方法来跟踪和管理他们的健康状况,因此医疗产品开始转向更多的健康预防领域。医疗器械设计公司认为,随着医疗产品设计从医疗产品转向家庭,医疗产品的设计需要考虑更多的新问…

【HTML+CSS+JavaScript】实现简单网页版的飞机大战

文章目录【HTMLCSSJavaScript】实现简单网页版的飞机大战一. HTML部分代码二. CSS部分代码三. JavaScript部分代码四. 完整的代码和图片获取【HTMLCSSJavaScript】实现简单网页版的飞机大战 本文分享的是键盘版飞机大战的代码,且文章末尾有惊喜。 效果图&#xff1a…

前端食堂技术周刊第 64 期:Node.js 19、Interop 2022、SvelteKit 1.0、2022 Web 性能回顾、最流行的 Node.js

美味值:🌟🌟🌟🌟🌟 口味:冰糖雪梨 食堂技术周刊仓库地址:https://github.com/Geekhyt/weekly 本期摘要 Node.js 19 的新特性Interop 2022 年终更新SvelteKit 1.02022 Web 性能回…

Python爬虫学习第十二天---scrapy学习

Python爬虫学习第十二天—scrapy学习 一、scrapy的概念和流程 1、scrapy概念 Scrapy是一个Python编写的开源网络爬虫框架,它是一个被设计用于爬取网络数据、提取结构性数据的框架。Scrapy文档地址:http://scrapy-chs.readthedocs.io/zh_CN/1.0/intro/…

采用抓包的方式逆向获得谷歌翻译的API

文章目录最开始的尝试2022.12.26谷歌翻译API相关信息发送网址提交的数据不过不出意外的失败了实验去掉参数去掉Headers代码对返回结果进行解析完整代码最开始的尝试 谷歌的翻译API老是发生变化,我们需要自己动手来找到谷歌的翻译API,这样才是最稳妥的解决…

个人博客系统(前后端分离)

努力经营当下,直至未来明朗! 文章目录一、项目简介二、项目效果三、项目实现1. 软件开发的基本流程2. 博客系统 需求分析3. 博客系统 概要设计4. 创建maven项目5. 编写数据库操作的代码四、项目代码总结普通小孩也要热爱生活! 一、项目简介 …

Mac 音频转换器推荐 DRmare Audio Converter、Audi Free Auditor

Mac 音频转换器推荐 DRmare Audio Converter、Audi Free Auditor 给大家推荐两款 Mac 上的音频转换器,这两款转换器都可以转换苹果音乐,iTunes歌曲或者一些常规的音轨到MP3, FLAC, WAV, M4A, AAC格式等等,转换后我们就可以在所有的设备和播放…

stm32f407VET6 系统学习 day06 窗口看门狗, IIC 通信协议

1.独立看门狗,与窗口看门狗的差别 1. 差别1 : 窗口看门狗, 有上限 0x7F, 有下限 0x40 ,, 独立看门狗只有下限 0 2. 差别2: 时钟源不同, 独立看门狗:LSI 窗口…

【iMessage苹果推群发】苹果相册推它由pushchatkey.pem和pushchatcert.pem作为单独的文件使用

推荐内容IMESSGAE相关 作者推荐内容iMessage苹果推软件 *** 点击即可查看作者要求内容信息作者推荐内容1.家庭推内容 *** 点击即可查看作者要求内容信息作者推荐内容2.相册推 *** 点击即可查看作者要求内容信息作者推荐内容3.日历推 *** 点击即可查看作者要求内容信息作者推荐…

cut与分层抽样

个人觉得, 把分层抽样称为“分类采样”会更贴切一些。通常最基本的采样手段是:随机抽样,但是在很多场景下,随机抽样是有问题的,举一个简单的例子:如果现在要发起一个啤酒品牌知名度的调查问卷,我…

Improved Unsupervised Lexical Simplification with Pretrained Encoders 论文精读

Improved Unsupervised Lexical Simplification with Pretrained Encoders 论文精读InformationAbstract1 Introduction2 System Description2.1 Simplification Candidate Generation2.2 Substitution Ranking2.3 Obtaining Equivalence Scores3 End-to-end System Performanc…

好书推荐《C++17 in Detail》

无意中发现作者的博客(https://www.cppstories.com/)和这本书。这本书算是对C17新增特性较为全面的介绍,而且从实战出发,不流于语法细枝末节,简洁清晰,可以作为Scott Meyers那本非著名的《Effective Modern…