数据库数据太多跑不动怎么办?

栏目: IT技术 · 发布时间: 4年前

内容简介:随着业务的增长,MySQL中保存的数据会越来越多。此时,数据库很容易成为系统性能的一个瓶颈,单机存储容量、IO、CPU处理能力都有限,当单表的数据量达到1000W或100G以后,库表的增删改查操作面临着性能大幅下降的问题。

| 作者: 董泽锋,腾讯云数据库研发工程师,主要负责腾讯云TDSQL数据库研发和运维工作。

随着业务的增长,MySQL中保存的数据会越来越多。此时,数据库很容易成为系统性能的一个瓶颈,单机存储容量、IO、CPU处理能力都有限,当单表的数据量达到1000W或100G以后,库表的增删改查操作面临着性能大幅下降的问题。

分库分表是一种解决办法。 分库分表实际上就是对数据进行切分。

我们一般可以将数据切分,分为两种方式: 垂直 (纵向)切分和 水平 (横向)切分。

1

垂直切分

垂直切分常见有 垂直分库 和 垂直分表 两种。

1. 垂直分库

垂直分库就是根据业务耦合性,将关联度低的不同表存储在不同的数据库。

思想与“ 微服务治理 ”类似,将系统拆分为多个业务,每个业务使用自己单独的数据库。


比如下图:

数据库数据太多跑不动怎么办?

将应用拆分为客户、存款和贷款三个业务,每个业务使用自己单独的数据库。

2. 垂直分表

垂直分表是基于数据库中的表字段来进行的。业务中可能存在一些字段比较多的表,表中某些字段长度较大,这些长字段我们又只是偶尔需要用到,这时候我们就可以考虑将表进行垂直拆分了。

将某些不常用的,但是长度又很大的字段拎出来放到另外一张表。

MySQL底层是通过数据页存储的,一条记录占用空间过大会导致跨页,造成额外的性能开销。另外数据库以行为单位将数据加载到内存中,这样表中字段长度较短且访问频率较高,内存能加载更多的数据,命中率更高,减少了磁盘IO,从而提升了数据库性能。

垂直切分例子如下图:

数据库数据太多跑不动怎么办?

我们将一张包含4个字段的表拆分为2张表,在业务代码里面,通过字段C1来进行关联。

3. 垂直切分优缺点

优点:

  1. 不同系统可以使用不同的库表,解决业务系统层面的耦合,业务清晰;

  2. 高并发场景下,垂直切分一定程度地提升IO、数据库连接数,缓解单机硬件资源的瓶颈。

缺点:

  1. 部分查询需要在业务代码逻辑里面做聚合,增加开发复杂度;

  2. 事务处理复杂,可能需要在业务代码层面做处理;

  3. 不能根本解决单表数据量过大的问题。

1

水平切分

当业务难以更细粒度地进行垂直切分,或者切分后单表数据依然过大,存在单库读写、存储性能瓶颈时候,这时候就可以考虑水平切分了。

水平切分又可以分为 库内分表 和 分库分表。

水平切分是根据表内数据的内在逻辑关系,将同一个表按不同的条件分散到多个数据库或多个表中,每个表中只包含一部分数据,从而使得单个表的数据量变小,达到分布式的效果。

1. 库内分表

库内分表就是在同一个DB上,将表按照某种条件拆分为多张表。

比如一张订单表,我们可以依据订单的日期,按月建表。一月份的订单放month_201901这张表,二月份的订单放month_201902这张表。

库内分表只解决单表数据量过大问题,但没有将表分布到不同机器上, 所有请求还是在一台物理机上竞争cpu、内存、IO ,对于减轻 mysql 负载压力来说帮助不大。

2. 分库分表

分库分表就是将表不仅拆分,而且拆分到不同机器上。

比如我们腾讯云上的DCDB就是这种处理方法。可以指定一张表的shardKey,然后对shardKey取hash,根据hash值将数据放到不同的数据库中, 可以解决单机物理资源的瓶颈问题

分库分表的示例如下:

数据库数据太多跑不动怎么办?

上面示例先根据业务耦合性垂直分库,然后再针对单个库进行分库分表。

3. 分库分表优缺点

优点:

  1. 不存在单库数据量过大、高并发的性能瓶颈,提升系统稳定性和负载能力;

  2. 应用端改造较小,不需要拆分业务模块。

缺点:

  1. 跨分片的事务一致性较难保障,一般需要一层中间件,介于业务和DB之间。对应腾讯云上的DCDB数据库所包含的Proxy层;

  2. 跨库的join关联查询性能较差。

1

分库分表带来的问题

分库分表能有效地缓解单机和单库带来的性能瓶颈和压力,突破网络IO、磁盘存储、CPU处理能力的瓶颈,同时也带来了一些问题。

1. 事务一致性问题

当更新内容同时分布在不同库中,不可避免会带来跨库事务问题。跨分片事务也是分布式事务,没有简单的方案,一般可使用”XA协议”和”两阶段提交”处理。

分布式事务能最大限度保证数据库操作的原子性,但在提交事务时需要协调多个节点,推后了提交事务的时间点,延长了事务的执行时间。导致事务在访问共享资源时发生冲突或死锁的概率增高。随着数据库节点的增多,这种趋势会越来越严重,从而成为系统在数据库层面上水平扩展的枷锁。

2. 跨节点关联查询 join 问题

切分之前,系统中很多列表和详情页所需的数据可以通过sql join来完成,而切分之后,数据可能分布在不同的节点上,此时join带来的问题就比较麻烦了,考虑到性能,尽量避免使用join查询。

解决这个问题的一些方法:

2.1)全局表:

全局表,也可看做是”数据字典表”,就是系统中所有模块都可能依赖的一些表,为了避免跨库join查询,可以将这类表在每个数据库中都保存一份。这些数据通常很少会进行修改,所以也不担心一致性的问题。比如腾讯云上的DCDB,可以创建广播表,其实就是全局表。每个节点都有该表的全量数据,该表的所有操作都将广播到所有物理分片(set)中。

2.2)字段冗余

一种典型的反范式设计,利用空间换时间,为了性能而避免join查询。例如:订单表保存userId时候,也将userName冗余保存一份,这样查询订单详情时就不需要再去查询”买家user表”了。

但这种方法适用场景也有限,比较适用于依赖字段比较少的情况。而冗余字段的数据一致性也较难保证,就像上面订单表的例子,买家修改了userName后,是否需要在历史订单中同步更新呢?这也要结合实际业务场景进行考虑。

2.3)数据组装

在系统层面,分两次查询,第一次查询的结果集中找出关联数据id,然后根据id发起第二次请求得到关联数据,最后将获得到的数据进行字段拼装。

3. 跨节点分页、 排序 、函数问题

跨节点多库进行查询时,会出现limit分页、order by排序等问题。分页需要按照指定字段进行排序,当排序字段就是分片字段时,通过分片规则就比较容易定位到指定的分片。

当排序字段非分片字段时,就变得比较复杂了。需要先在不同的分片节点中将数据进行排序并返回,然后将不同分片返回的结果集进行汇总和再次排序,最终返回给用户。显然这个过程是会降低查询的效率,对IO,CPU也会增加额外负担。

如下图所示:

数据库数据太多跑不动怎么办?

上图中只是取第一页的数据,对性能影响还不是很大。但是如果取得页数很大,情况则变得复杂很多,因为各分片节点中的数据可能是随机的,为了排序的准确性,需要将所有节点的前N页数据都排序好做合并,最后再进行整体的排序,这样的操作是很耗费CPU和内存资源的,所以页数越大,系统的性能也会越差。

在使用Max、Min、Sum、Count之类的函数进行计算的时候,也需要先在每个分片上执行相应的函数,然后将各个分片的结果集进行汇总、再次计算,最终将结果返回。

4. 全局主键避重问题

在分库分表环境中,由于表中数据同时存在不同数据库中,主键平时使用的自增长将无用武之地,某个分区数据库自生成的ID无法保证全局唯一。 因此需要单独设计全局主键,以避免跨库主键重复问题。

1

分库分表可以解决一些问题(比如单机的IO,CPU、磁盘瓶颈问题),但也增添了一些新问题(比如事务一致性问题,跨分片join问题)。 当然随着一些新的NewSQL技术的成熟,分库分表这一方案也不再是业务扩张后的最优选择了,腾讯自研云原生数据库 CynosDB就给出了更优的解决方案。

往期推荐

数据库数据太多跑不动怎么办?

(点击图片即可跳转阅读)

数据库数据太多跑不动怎么办?

开年大礼包 

数据库数据太多跑不动怎么办?

↓↓更多惊喜优惠请点这儿~


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Google

Google

托马斯·舒尔茨(Thomas·Schulz) / 严孟然、陈琴 / 当代中国出版社 / 2016-11-1 / CNY 49.80

想要掌握未来,必须了解谷歌 1998年从车库起家,短短数年研发上千项专利,2016年力压苹果、亚马逊,成为“世界最具价值品牌”“最佳雇主”,谷歌无疑是互联网时代的最大赢家,这家公司有能力通过巨额广告利润收获现在,更有意愿在人工智能层面创造未来。 据说谷歌势不可挡,永不餍足。从互联网搜索到智能翻译再到地图导航,谷歌是我们通向世界的门户。不仅如此,就像管理全世界的数据流一样,谷歌还要在不久......一起来看看 《Google》 这本书的介绍吧!

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

在线进制转换器
在线进制转换器

各进制数互转换器

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具