分库分表平滑扩容

对于咱们经常使用的分库分表方案来讲,有很大的优点,分库分表的扩容是一件头疼的问题,若是采用对db层作一致性hash,或是中间价的支持,它的成本过于高昂了,若是不如此,只能停机维护来处理,对高可用性会产生影响。算法

那是否有方案,既能够快速扩展,又不下降可用性?这一篇,咱们聊聊分库分表的扩展方案,供你们一块儿探讨。数据库

1、水平分库扩展问题

为了增长db的并发能力,常见的方案就是对数据进行sharding,也就是常说的分库分表,这个须要在初期对数据规划有一个预期,从而预先分配出足够的库来处理。安全

好比目前规划了3个数据库,基于uid进行取余分片,那么每一个库上的划分规则以下:服务器

水平分库如何作到平滑扩展

如上咱们能够看到,数据能够均衡的分配到3个数据库里面。网络

可是,若是后续业务发展的速度很快,用户量数据大量上升,当前容量不足以支撑,应该怎么办?并发

须要对数据库进行水平扩容,再增长新库来分解。新库加入以后,原先sharding到3个库的数据,就能够sharding到四个库里面了工具

水平分库如何作到平滑扩展

不过此时因为分片规则进行了变化(uid%3 变为uid%4),大部分的数据,没法命中在原有的数据库上了,须要从新分配,大量数据须要迁移。ui

好比以前uid1经过uid1%3 分配在A库上,新加入库D以后,算法改成uid1%4 了,此时有可能就分配在B库上面了。若是你有看到以前《一致性哈希的原理与实践》,就会发现新增一个节点,大概会有90%的数据须要迁移,这个对DB同窗的压力仍是蛮大的,那么如何应对?blog

通常有如下几种方式。开发

2、停服迁移

停服迁移是最多见的一种方案了,通常以下流程:

  1. 预估停服时间,发布停服公告

  2. 停服,经过事先作好的数据迁移工具,按照新的分片规则,进行迁移

  3. 修改分片规则

  4. 启动服务

咱们看到这种方式比较安全,停服以后没有数据写入,可以保证迁移工做的正常进行,没有一致性的问题。惟一的问题,就是停服了和时间压力了。

  1. 停服,伤害用户体验,同时也下降了服务器的可用性

  2. 必须在制定时间内完成迁移,若是失败,须要择日再次进行。同时增长了开发人员的压力,容易发生大的事故

  3. 数据量的巨大的时候,迁移须要大量时间

那有没有其余方式来改进一下,咱们看下如下两种方案。

3、升级从库

线上数据库,咱们为了保持其高可用,通常都会每台主库配一台从库,读写在主库,而后主从同步到从库。以下,A,B是主库,A0和B0是从库。

水平分库如何作到平滑扩展

此时,当须要扩容的时候,咱们把A0和B0升级为新的主库节点,如此由2个分库变为4个分库。同时在上层的分片配置,作好映射,规则以下:

uid%4=0和uid%4=2的分别指向A和A0,也就是以前指向uid%2=0的数据,分裂为uid%4=0和uid%4=2

uid%4=1和uid%4=3的指向B和B0,也就是以前指向uid%2=1的数据,分裂为uid%4=1和uid%4=3

由于A和A0库的数据相同,B和B0数据相同,因此此时无需作数据迁移便可。只须要变动一下分片配置便可,经过配置中心更新,无需重启。

水平分库如何作到平滑扩展

因为以前uid%2的数据分配在2个库里面,此时分散到4个库中,因为老数据还存在(uid%4=0,还有一半uid%4=2的数据),因此须要对冗余数据作一次清理。

而这个清理,不会影响线上数据的一致性,但是随时随地进行。

处理完成之后,为保证高可用,以及下一步扩容需求。能够为现有的主库再次分配一个从库。

水平分库如何作到平滑扩展

总结一下此方案步骤以下:

  1. 修改分片配置,作好新库和老库的映射。

  2. 同步配置,从库升级为主库

  3. 解除主从关系

  4. 冗余数据清理

  5. 为新的数据节点搭建新的从库

4、双写迁移

双写的方案,更多的是针对线上数据库迁移来用的,固然了,对于分库的扩展来讲也是要迁移数据的,所以,也能够来协助分库扩容的问题。

原理和上述相同,作分裂扩容,只是数据的同步方式不一样了。

1.增长新库写连接

双写的核心原理,就是对须要扩容的数据库上,增长新库,并对现有的分片上增长写连接,同时写两份数据。

由于新库的数据为空,因此数据的CRUD对其没有影响,在上层的逻辑层,仍是以老库的数据为主。

水平分库如何作到平滑扩展

2.新老库数据迁移

经过工具,把老库的数据迁移到新库里面,此时能够选择同步分裂后的数据(1/2)来同步,也能够全同步,通常建议全同步,最终作数据校检的时候好处理。

水平分库如何作到平滑扩展

3.数据校检

按照理想环境状况下,数据迁移以后,由于是双写操做,因此两边的数据是一致的,特别是insert和update,一致性状况很高。但真实环境中会有网络延迟等状况,对于delete状况并非很理想,好比:

A库删除数据a的时候,数据a正在迁移,尚未写入到C库中,此时C库的删除操做已经执行了,C库会多出一条数据。

此时就须要作好数据校检了,数据校检能够多作几遍,直到数据几乎一致,尽可能以旧库的数据为准。

4.分片配置修改

数据同步完毕,就能够把新库的分片映射从新处理了,仍是按照老库分裂的方式来进行,

u以前uid%2=0,变为uid%4=0和uid%4=2的

uid%2=1,变为uid%4=1和uid%4=3的。

水平分库如何作到平滑扩展

相关文章
相关标签/搜索