昨天我们分享了怎么不停机进行分库分表数据迁移(数据库分库分表后,我们生产环境怎么实现不停机数据迁移)后来有好多朋友问我,说他们的系统虽然也到了差不多分表的地步了,但是,不知道具体拆分多少张表,分多了又怕浪费公司资源,分少了又怕后面怎么去扩容,还有另一些朋友说,所在的公司规模还不大,尚在发展中,公司压根就没这么资源给他们这么去拆分。
这些朋友的问题提的很好,因为真正的结合自己公司的业务去思考了。所以,我今天就来帮助解答下,并且帮着更多有类似困扰的朋友进行统一的讲解,教大家该怎么去做,掌握这套思想之后,其实你们就能举一反三了,我相信,今天学完之后,你们就可以解开自己的心中疑惑了。
好,那我们就来进入正题。其实上面提到的那些问题,就是归类到一个问题上,那到底是什么呢?就是我们分库分表怎么去动态扩容的问题。你现在想想看是不是,你开始不知道分多少库表,在分多或者分少只中进行纠结,还担心自己的资源不够等等,这些都是因为不知道怎么去动态扩容。下面我们就来看看,我们的数据库分库分表,该怎么去动态扩容。
01
笨方法扩容(强烈不推荐)
既然是强烈不推荐的笨方法,我为什么还要说呢?因为这种方法的确有部分人这么干,简单粗暴还累人。那究竟是什么样的累人方式呢,我想大家应该猜得到的,和前面停机数据迁移类似,但是这个比首次停机迁移要复杂得多。
比如,开始分库分表的时候,是这样想的,由于想着我们公司资源有限,或者是不知道该分多少,就先随便分几个试试,所以我们现在就将原单库表分了 2 个库每个库分 4 张表类似这样的。谁知道,咱们公司业务发展速度惊人,我们之前分的2 * 8的库表完全不满足现在的业务需求。
这个时候,就有人这么干了,没事啊,我们就像我们之前那样嘛,不管是停机的还是在线的,同样写一个后台数据迁移程序,将现在的这些库表全查出来,然后我们用新的hash策略进行路由到我们新的这些库表不就行了,比如以前是对2 和4 进行哈希的,现在改成了 4和8进行哈希库表了。如果分库分表策略忘了的可以回去看看(数据库分库分表方案,优化大量并发写入所带来的性能问题),真的有这么干的。
我不知道你们会不会想到这么干,但是我的确见过这么干的,包括我们自己公司有些小组也有这么想的,但是我现在可以告诉你,就此打断这个念头了,为什么不建议你们这么做呢?
- 首先显得你自己非常的不专业,更是吃力不讨好的活。
- 本来我们开始单库表数据分库分表的时候,数据就巨多了,至少得千万级别的吧,我们是到了亿的时候采取分的,你想想看,你分了2*4的库表之后,现在还想用之前的流程再来,那数据可不是一个量级的,几十亿的数据很正常,你如果这样的去查出来,再去重新hash入库在校验。这么一来,你几个小时能搞定吗?显然不能的啊。
- 万一要是出错了,还得重新回滚再来,那时你就会特别懊恼吧,懊恼之后就更会出错。所以,这里我强烈不推荐你这么干,因为真的很不靠谱还累了你自己,活还不一定能出来。
02
分库分表动态扩容
上面我和大家提到了不能直接通过写程序工具来再次查询数据来进行扩容,也说了为什么不推荐那么做,只是想让大家现在看到了就尽量去避免踩坑。下面我们就来看看比较靠谱的扩容方法,也就是动态扩容,那我们该怎么使用这种方案呢?
核心思想
在分库分表策略那篇文章,我就建议,如果不用分库分表我们坚决不去分库分表。如果是到了分库分表的地步了,我们最好就是一次性分到位,比如分个32 * 32的这样的规模,目的就是防止出现扩容的复杂性,所以,今天这个问题也就引出来了。
这个时候,你们可能还是会说,我们公司就是资源有限了,你还让我一次性分到位,公司没那么多机器给我做这些数据库分库分表。的确,这个问题是有,因为大家所身处的公司,并不是都是行业数一数二,资源充分。但是没关系啊,不影响我们做架构,是什么意思呢?
我的意思是说,我在做分库分表架构时,不一定非得一开始就要将一个数据库服务器放一个MySql数据库啊,我可以在一个数据库服务器上放多个MySQL实例啊,对吧。比如,现在我一次性分32个库每个库32张表。你就给我 4 台 数据库服务器,然后我每一台部署 8 个MySQL数据库实例,这样子的来弄,并不非得要求一个数据库一台服务器。最次的话,如果你公司真的抠的话,可以只给我一台好的配置的,我把32个数据库都放在一台服务器总行吧,当然这么抠的毕竟少数哈。
03
如何动态扩容
在我们数据库分库分表动态扩容的时候,我们要搞清楚目前造成我们急需扩容的原因是什么?是什么原因直接会触发我们扩容,也就是我们要扩容的动机。一般有两个原因会直接触发我们的扩容。
数据库并发瓶颈,也就是当前你给我的那四台机器啊,随着业务的猛增,相关请求并发已经超过了我们现在数据库服务器的并发范围
和以前一样,现在分的库表数据已经快满了,当前数据库表装不下了,又到了上亿的数据,服务器磁盘容量也不够存储了,这个时候我们就需要对其进行扩容
- 首次分库分表时,我一次性分为32 * 32这样的,即分成32个库,然后每个库 32 张表。
- 现在你就给我 4 台数据库服务器,那我就在每台数据库服务器上搭建 8 个MySQL数据库实例,每个库32张表。
- 现在随着公司业务的发展,我们的四台数据库服务器达到了并发或者磁盘瓶颈,我们这个时候我们又要对其进行拆分,当然这里就是直接动态扩容了,不需要在单独拆分了。比如,我们根据目前业务增长的势头分析,再将其扩容四台机器出来(公司业务这么好,如果你还说没资源,那就说不过去了吧),将之前的每台数据库服务器上数据库分一半出来到新的数据库服务器上来,即现在一共有 8 个数据库服务器,然后每台服务器分 4 个数据库,每个数据 32 张表。
- 如果业务继续上升,又需要扩容,这个时候还是可以按照上面逻辑来动态扩容,在不用动业务代码的情况下,我们可以扩到 32 台数据库服务器,每台放一个数据库。这种的规模一般可以支撑你好多好多年的业务了。
动态扩容有什么优点:
- 节省我们开发人员的时间,扩容过程很愉快。
- 不用再哈希路由,直接整个数据库移动,原有数据压根不用动,你说开心不开心。
- 提高并发性能
- 提高磁盘利用率
建议:
这里我有个建议需要跟大家说一下,在hash路由表的时候,如果只是hash 表32的话,会有可能不太均匀,所以建议大家在hash的时候,先对32取整,然后在对32 取余即如下:
- 路由库:ID % 32
- 路由表:ID / 32 , 然后得到的整数 % 32
总结,今天我们分享了我们在不知道将分多少库表的问题做了个针对性的讲解,并且教大家怎么去应对分库分表的动态扩容,而不用我们自己写代码重新哈希路由,我相信,到今天,大家肯定对分库分表这样的专题定会有了更全面的认知。