数据库为什么要分库分表
为什么要分库分表
1.1 数据库性能瓶颈的出现
对于应用来说,如果数据库性能出现问题,要么是无法获取连接,是因为在高并发的情况下连接数不够了。要么是操作数据变慢,数据库处理数据的效率除了问题。要么是存储出现问题,比如单机存储的数据量太大了,存储的问题也可能会导致性能的问题。归根结底都是受到了硬件的限制,比如 CPU,内存,磁盘,网络等等。但是我们优化肯定不可能直接从扩展硬件入手,因为带来的收益和成本投入比例太比。所以我们先来分析一下,当我们处理数据出现无法连接,或者变慢的问题的时候,我们可以从哪些层面入手。
1.2 数据库优化方案对比
数据库优化有很多层面。
- 1.2.1 SQL 与索引
因为 SQL 语句是在我们的应用端编写的,所以第一步,我们可以在程序中对 SQL 语句进行优化,最终的目标是用到索引。这个是容易的也是最常用的优化手段。
- 1.2.2 表与存储引擎
第二步,数据是存放在表里面的,表又是以不同的格式存放在存储引擎中的,所以我们可以选用特定的存储引擎,或者对表进行分区,对表结构进行拆分或者冗余处理,或者对表结构比如字段 的定义进行优化。
- 1.2.3 架构
第三步,对于数据库的服务,我们可以对它的架构进行优化。如果只有一台数据库的服务器,我们可以运行多个实例,做集群的方案,做负载均衡。或者基于主从复制实现读写分离,让写的服务都访问 master 服务器,读的请求都访问从服务器,slave 服务器自动 master 主服务器同步数据。或者在数据库前面加一层缓存,达到减少数据库的压力,提升访问速度的目的。为了分散数据库服务的存储压力和访问压力,我们也可以把不同的数据分布到不同的服务节点,这个就是分库分表(scale out)。注意主从(replicate)和分片(shard)的区别:主从通过数据冗余实现高可用,和实现读写分离。
分片通过拆分数据分散存储和访问压力。
- 1.2.4 配置
第四步,是数据库配置的优化,比如连接数,缓冲区大小等等,优化配置的目的都是为了更高效地利用硬件。
- 1.2.5 操作系统与硬件
最后一步操作系统和硬件的优化。从上往下,成本收益比慢慢地在增加。所以肯定不是查询一慢就堆硬件,堆硬件叫做向上的扩展(scale up)。
什么时候才需要分库分表呢?我们的评判标准是什么?
- 如果是数据量的话,一张表存储了多少数据的时候,才需要考虑分库分表?
- 如果是数据增长速度的话,每天产生多少数据,才需要考虑做分库分表?
- 如果是应用的访问情况的话,查询超过了多少时间,有多少请求无法获取连接,才需要分库分表?
这是一个值得思考的问题。
1.3 架构演进与分库分表
- 1.3.1 单应用单数据库
一个消费金融核心系统,是一个典型的单体架构的应用。同学们应该也很熟悉,单体架构应用的特点就是所有的代码都在一个工程里面,打成一个 war 包部署到 tomcat,最后运行在一个进程中。这套消费金融的核心系统,用的是 Oracle 的数据库,初始化以后有几百张表,比如客户信息表、账户表、商户表、产品表、放款表、还款表等等。
![](https://img2020.cnblogs.com/blog/1585156/202009/1585156-20200912003404119-733644587.jpg)
为了适应业务的发展,我们这一套系统不停地在修改,代码量越来越大,系统变得越来越臃肿。为了优化系统,我们搭集群,负载均衡,加缓存,优化数据库,优化业务代码系统,但是都应对不了系统的访问压力。
![](https://img2020.cnblogs.com/blog/1585156/202009/1585156-20200912003644871-1221666313.jpg)
所以这个时候系统拆分就势在必行了。我们把以前这一套采购的核心系统拆分出来很多的子系统,比如提单系统、商户管理系统、信审系统、合同系统、代扣系统、催收系统,所有的系统都依旧共用一套 Oracle 数据库。
- 1.3.2 多应用单数据库
对代码进行了解耦,职责进行了拆分,生产环境出现问题的时候,可以快速地排查和解决。
![](https://img2020.cnblogs.com/blog/1585156/202009/1585156-20200912003644871-1221666313.jpg)
这种多个子系统共用一个 DB 的架构,会出现一些问题。第一个就是所有的业务系统都共用一个 DB,无论是从性能还是存储的角度来说,都是满足不了需求的。随着我们的业务继续膨胀,我们又会增加更多的系统来访问核心数据库,但是一个物理数据库能够支撑的并发量是有限的,所有的业务系统之间还会产生竞争,最终会导致应用的性能下降,甚至拖垮业务系统。
- 1.3.3 多应用独立数据库
所以这个时候,我们必须要对各个子系统的数据库也做一个拆分。这个时候每个业务系统都有了自己的数据库,不同的业务系统就可以用不同的存储方案。
![](https://img2020.cnblogs.com/blog/1585156/202009/1585156-20200912004002274-139755000.jpg)
所以,分库其实是我们在解决系统性能问题的过程中,对系统进行拆分的时候带来的一个必然的结果。现在的微服务架构也是一样的,只拆应用不拆分数据库,不能解决根本的问题。
- 1.3.4 什么时候分表?
当我们对原来一个数据库的表做了分库以后,其中一些表的数据还在以一个非常快。的速度在增长,这个时候查询也已经出现了非常明显的效率下降。所以,在分库之后,还需要进一步进行分表。当然,我们最开始想到的可能是在一个数据库里面拆分数据,分区或者分表,到后面才是切分到多个数据库中。分表主要是为了减少单张表的大小,解决单表数据量带来的性能问题。
![](https://img2020.cnblogs.com/blog/1585156/202009/1585156-20200912004230779-985010654.png)
我们需要清楚的是,分库分表会提升系统的复杂度,如果在近期或者未来一段时间内必须要解决存储和性能的问题,就不要去做超前设计和过度设计。就像我们搭建项目,从快速实现的角度来说,肯定是从单体项目起步的,在业务丰富完善之前,也用不到微服务架构。如果我们创建的表结构合理,字段不是太多,并且索引创建正确的情况下,单张表存储几千万的数据是完全没有问题的,这个还是以应用的实际情况为准。当然我们也会对未来一段时间的业务发展做一个预判。