# (五)可以动态扩容缩容的分库分表方案

#### 1.扩容与缩容

这个是你必须面对的一个事儿，就是你已经弄好分库分表方案了，然后一堆库和表都建好了，基于分库分表中间件的代码开发啥的都好了，测试都ok了，数据能均匀分布到各个库和各个表里去，而且接着你还通过双写的方案咔嚓一下上了系统，已经直接基于分库分表方案在搞了。

那么现在问题来了，你现在这些库和表又支撑不住了，要继续扩容咋办？这个可能就是说你的每个库的容量又快满了，或者是你的表数据量又太大了，也可能是你每个库的写并发太高了，你得继续扩容。

缩容就是现在业务不景气了，数据量减少，并发量下降，那么不能让他占着太多的数据库啊，肯定要进行缩容。

#### 2.停机扩容

①**原理**\
这个方案就跟停机迁移一样，步骤几乎一致，唯一的一点就是那个导数的工具，是把现有库表的数据抽出来慢慢倒入到新的库和表里去。但是最好别这么玩儿，有点不太靠谱，因为既然分库分表就说明数据量实在是太大了，可能多达几亿条，甚至几十亿，你这么玩儿，可能会出问题。

从单库单表迁移到分库分表的时候，数据量并不是很大，单表最大也就两三千万。写个工具，多弄几台机器并行跑，1小时数据就导完了

如果经过分库分表之后，那么数据量肯定会非常大，那么这种方案的耗时会太长。

#### 3.优雅设计扩容缩容

优雅的设计扩容缩容的意思就是 进行扩容缩容的代价要小，迁移数据要快。

可以采用逻辑分库分表的方式来代替物理分库分表的方式，要扩容缩容时，只需要将逻辑上的数据库、表改为物理上的数据库、表。

第一次进行分库分表时就多分几个库，一个实践是利用32 \* 32来分库分表，即分为32个库，每个库32张表，一共就是1024张表，根据某个id先根据先根据数据库数量32取模路由到库，再根据一个库的表数量32取模路由到表里面。

刚开始的时候，这个库可能就是逻辑库，建在一个mysql服务上面，比如一个mysql服务器建了16个数据库。

如果后面要进行拆分，就是不断的在库和mysql实例之间迁移就行了。将mysql服务器的库搬到另外的一个服务器上面去，比如每个服务器创建8个库，这样就由两台mysql服务器变成了4台mysql服务器。我们系统只需要配置一下新增的两台服务器即可。

比如说最多可以扩展到32个数据库服务器，每个数据库服务器是一个库。如果还是不够？最多可以扩展到1024个数据库服务器，每个数据库服务器上面一个库一个表。因为最多是1024个表么。

这么搞，是不用自己写代码做数据迁移的，都交给dba来搞好了，但是dba确实是需要做一些库表迁移的工作，但是总比你自己写代码，抽数据导数据来的效率高得多了。

哪怕是要减少库的数量，也很简单，其实说白了就是按倍数缩容就可以了，然后修改一下路由规则。

②**分库分表路由规则**\
对库可以进行根据库的数量取模决定库的路由。\
对表可以先根据表的数量进行整除，然后将结果再对表的数量进行取模，这样可以跟均匀的分布。

③**过程**\
1、设定好几台数据库服务器，每台服务器上几个库，每个库多少个表，推荐是32库 \* 32表，对于大部分公司来说，可能几年都够了

2、路由的规则，orderId 模 32 = 库，orderId / 32 模 32 = 表

3、扩容的时候，申请增加更多的数据库服务器，装好mysql，倍数扩容，4台服务器，扩到8台服务器，16台服务器

4、由dba负责将原先数据库服务器的库，迁移到新的数据库服务器上去，很多工具，库迁移，比较便捷

5、我们这边就是修改一下配置，调整迁移的库所在数据库服务器的地址

6、重新发布系统，上线，原先的路由规则变都不用变，直接可以基于2倍的数据库服务器的资源，继续进行线上系统的提供服务
