1 面试题
设计可动态扩容的分库分表
2 考点分析
- 选一个数据库中间件,然后深入之
- 设计分库分表的方案,要分成多少个库,每个库分成多少个表
- 基于已选的数据库中间件,以及在测试环境建立好的分库分表,????能否正常执行分库分表的读写
- 完成单库单表到分库分表的迁移(使用上一文提到的双写方案)
- 线上系统,开始基于分库分表对外服务
突然! 扩容了,扩容成6个库,每个库需要12个表,你怎么来增加更多库和表呢?
这个你必须面对的事,就是当你已经弄好分库分表方案,测试也通过了,数据能均匀分布到各个库和表里去,而且接着你还通过双写方案上了系统,已经直接基于分库分表方案在搞了。
需求来了~现在这些库和表又支撑不住了,要继续扩容,咋办?
这个可能就是每个库的容量又快满了,或者表数据量又太大了,也可能每个库的写并发太高了,得继续扩容!
3 停机扩容(不推荐)
这就跟停机迁移一样,步骤几乎一致,唯一不同是导数的工具,是把现有库表的数据抽出来慢慢导入到新的库和表里去。但是最好别这样,有点不太靠谱,既然分库分表,就说明数据量实在太大了,你这么玩,可能会出问题!
从单库单表迁移到分库分表时,数据量并不是很大,单表最大也就两三千万
写个工具,多弄几台机器并行跑,1小时数据就导完了
但如果是:3个库+12个表
跑了一段时间了,数据量都1亿~2亿了
光是导2亿数据,都要导个几个小时,6点,刚刚导完数据,还要搞后续的修改配置,重启系统,测试验证,10点才可以搞完!
4 优化方案
一开始上来就是32个库,每个库32个表,1024张表
这个分法
- 基本上国内的互联网肯定都够用
- 无论并发支撑还是数据量支撑都没问题
每个库正常承载的写入并发量是1000,那么32个库就可以承载32 * 1000 = 32000
的写并发
如果每个库承载1500的写并发,32 * 1500 = 48000
的写并发,接近5万/s的写入并发
前面再加个MQ,削峰,每秒写入MQ 8万条数据,每秒消费5万条数据
1024张表,假设每个表放500万数据,在MySQL里可以放50亿条数据
每秒的5万写并发,总共50亿条数据,对于国内大部分互联网公司来说都够了
谈分库分表的扩容,第一次分库分表,就一次性给他分个够
32个库,1024张表,对大部分的中小型互联网公司来说,已经可以支撑好几年
一个实践是利用32 * 32
来分库分表,即分为32个库,每个库里一个表分为32张表,一共就是1024张表
根据某个id先根据32取模路由到库,再根据32取模路由到库里的表。
刚开始的时候,这个库可能就是逻辑库,建在一个数据库上的
也就是一个MySQL服务器可能建了n个库,后面如果要拆分,就不断在库和MySQL服务器之间做迁移就可以了。然后系统配合改一下配置即可。
比如说最多可以扩展到32个数据库服务器,每个数据库服务器是一个库。如果还是不够?
最多可以扩展到1024个数据库服务器,每个数据库服务器上面一个库一个表。因为最多是1024个表
这么搞,是不用自己写代码做数据迁移的,都交给DBA来搞好了,但是DBA确实需要做一些库表迁移的工作,总比你自己写代码,抽数据导数据来的效率高得多
哪怕是要减少库的数量,也很简单,按倍数缩容就可以了,然后修改一下路由规则。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yVGgjByD-1610165288140)(https://ask.qcloudimg.com/http-save/1752328/rprqxeb7cn.png)]
5 总结
5.1 确定方案
几台数据库服务器,每台服务器上几个库,每个库多少个表,推荐是32库 * 32表
,对于大部分公司来说,可能几年都够了
5.2 路由规则
orderId 模 32 = 库,orderId / 32 模 32 = 表
5.3 扩容
当扩容时,申请增加更多的数据库服务器,装好MySQL,倍数扩容,4台服务器,扩到8台服务器,16台服务器
5.4 迁移
由DBA负责将原先数据库服务器的库,迁移到新的数据库服务器上去,很多工具,库迁移,比较便捷
5.5 配置
我们这边就是修改一下配置,调整迁移的库所在数据库服务器的地址
5.6 发布
重新发布系统,上线,原先的路由规则变都不用变,直接可以基于2倍的数据库服务器的资源,继续进行线上系统的提供服务
- 分库分表扩容方案[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QvzpAbDO-1610165288143)(https://ask.qcloudimg.com/http-save/1752328/88hu11t4xh.png)]
参考
- 《Java工程师面试突击第1季-中华石杉老师》