行业资讯

最新动态、技术干货,汇聚前沿的云计算技术

阿里云RDS分库分表扩容兑现平滑数据迁移

唯一小编 发布时间:2021-03-01 返回

唯一网络成立于2006年,是国内知名的云服务综合解决方案提供商。专业提供云服务器服务器租用托管云专线云等保一键免费获取方案等一站式云服务综合解决方案提供商。

新用户注册就送千元大礼包销售咨询热线:0769-23015555。

2020年,笔者负责的一个高德打车弹外订单系统进行了一次扩分库分表和数据库迁移。该订单系统全局部署在阿里云上,服务应用阿里云ECS部署,数据库采纳阿里云RDS,配置中心基于阿里云ACM自研,数据同步基于阿里云DTS自研以及自研分库分表组件、分布式ID组件等等。

阿里云RDS分库分表扩容兑现平滑数据迁移

此次进行扩分库分表的背景是,原4实例4库、各个库64张表一共256张表,部分单表已超千万量级,按目前每日单量量级,一年内单表会达到上亿条记载,单表数据量过大会带来数据库性能问题。

4实例(16C/64G/3TSSD),4库(各个实例一个库),每库64张表,共256张表。

经过RDS后台一键诊断功能,来计算表空间应用情形(这里拿测试情境数据库举例)。

数据库的瓶颈主要表现在:磁盘、CPU、内存、互联网、联结数,而联结数主要是受CPU和内存作用。CPU和内存可以经过动态升配来提高,可是SSD磁盘容量最大支持到6T(32C以下最大3T、32C及以上最大6T)。

可是现阶段兼顾成本,可先将实例扩容一倍,采纳8个实例(16C/64G/3TSSD),各个实例建4个库(database)、各个库128张表(这里实质上是一个成本取舍的流程,理论上应该采取”多库少表”的准则,单库128张表其实太多了,单库建议32或64张表为宜)。

接下来如果实例压力提高可进行实例配置改进(16C/128G、32C/128G、32C/256G等);将来如出现单实例升配无法解决,在考虑扩容实例,只需求将database迁移至新实例,迁移成本较小。

按单表最多1000w条数据评估,4096张表可支持日5000w单3年(10.1压测标准)、日2000w单5年的架构。(因业务表比较多,此处忽略掉单条数据大小的计算流程)

32个库,各个库128张表。将来可最大扩容到32个实例,无需rehash,只需求迁移数据。

阿里云RDS规格和价钱一览

因扩分库分表涉及到rehash流程(256表变4096表),而阿里云DTS只支持同构库数据迁移,所以我们基于DTS的binlog转kafka实力自研了数据同步中间件。

整体数据迁移工作包含:前期预备、数据同步环节(历史数据全量同步、增量数据实时同步、rehash)、数据校验环节(全量校验、实时校验、校验规章配置)、数据修复工具等。

在进行数据同步前,需求先整理一切表的惟一业务ID,只有确定了惟一业务ID才学兑现数据的同步操作。

需求重视的是:

一旦表中没有惟一索引,就会在数据同步流程中造成数据重复的危险,所以我们先将没有惟一索引的表依据业务场景增加惟一索引(有也许是联合惟一索引)。

在这里顺便提一下,阿里云DTS做同构数据迁移,应用的是数据库自增ID做为惟一ID应用的,这种情形如果做双向同步,会造成数据覆盖的问题。解决案例也有,之前我们的做法是,新旧实物采纳自增ID单双号解决,担保新旧实例的自增ID不会出现冲突就行。由于这次我们应用的自研双向同步组件,这个难题这里不细聊。

分表规章不同决定着rehash和数据校验的不同。需逐个表整理是用户ID纬度分表还是非用户ID纬度分表、是否只分库不分表、是否不分库不分表等等。

数据同步全局案例见下图,数据同步基于binlog,独立的中间服务做同步,对业务代码无侵入。

后续对每一个环节进行介绍。

单独一个服务,应用游标的方法从旧库分批select数据,通过rehash后批量插入(batchinsert)到新库,此处需求配置jdbc联结串参数rewriteBatchedStatements=true才学使批处理操作生效。

另外特殊需求重视的是,历史数据也会存在不断的更新,如果先开启历史数据全量同步,则刚同步达成的数据有也许不是最新的。所以这里的做法是,先开启增量数据单向同步(从旧库到新库),此时只是开启积压kafka消息并不会真正消费;然后在开始历史数据全量同步,当历史全量数据同步达成后,在开启消费kafka消息进行增量数据同步(提升全量同步效率变少积压也是核心的一环),这样来担保迁移数据流程中的数据一致。

增量数据同步考虑到灰度切流稳定性、容灾和可回滚实力,采纳实时双向同步案例,切流流程中一旦新库出现稳定性问题或者新库出现数据一致问题,可迅速回滚切回旧库,担保数据库的稳定和数据稳妥。

增量数据实时同步采纳基于阿里云DTS的数据订阅自研数据同步组件data-sync兑现,主要案例是DTS数据订阅实力会自动将被订阅的数据库binlog转为kafka,data-sync组件订阅kafka消息、将消息进行过滤、合并、分组、rehash、拆表、批量insert/update,最后再上交offset等一系列操作,最终达成数据同步工作。

整体流程中有几个问题需求重视:

问题1:怎样预防因异步消息无顺序而致使的数据一致问题?

第一kafka异步消息是存在顺序问题的,可是要知道的是binlog是顺序的,所以dts在对具体进行kafka消息投递时也是顺序的,此处要做的就是一个库担保只有一个顾客就能保障数据的顺序问题、不会出现数据状态覆盖,从而解决数据一致问题。

问题2:是否会有丢消息问题,假如顾客服务重启等情形下?

这里没有采纳自动上交offset,而是每次消费数据最终入库达成后,将offset异步存到一个mysql表中,如果顾客服务重启宕机等,重启后从mysql拿到最新的offset开始消费。这样惟一的一个问题也许会出现瞬间部分消息重复消费,可是由于上面介绍的binlog是顺序的,所以能担保数据的最终一致。

问题3:update转insert会不会丢字段?

binlog是全字段发送,不会存在丢字段情形。

问题4:循环消息问题。

后面进行单独介绍。

前文有提到,由于是256表变4096表,所以数据每一条都需求通过一次rehash重新做分库分表的计算。

要说rehash,就必须先介绍下目前订单数据的分库分表策略,订单ID中冗余了用户ID的后四位,经过用户ID后四位做hash计算确定库号和表号。

数据同步流程中,从旧库到新库,需求拿到订单ID中的用户ID后四位模4096,确定数据在新库中的库表位置;从新库到旧库,则需求用用户ID后四位模256,确定数据在旧库中的库表位置。

想象一下,业务写一条数据到旧实例的一张表,于是诞生了一条binlog;data-sync中间件接到binlog后,将该记载写入到新实例,于是在新实例也诞生了一条binlog;此时data-sync中间件又接到了该binlog……不断循环,消息愈来愈多,数据顺序也被打乱。

怎样解决该问题呢?我们采纳数据染色案例,只要能够标识写入到数据库中的数据使data-sync中间件写入而非业务写入,当下次接收到该binlog数据的时候就不必进行再次消息流转。

所以data-sync中间件需求,各个数据库实例创建一个事务表,该事务表tb_transaction只有id、tablename、status、create_time、update_time几个字段,status默认为0。

再回到上面的问题,业务写一条数据到旧实例的一张表,于是诞生了一条binlog;data-sync中间件接到binlog后,如下操作:

此时data-sync中间件将上面这些语句打包全体上交到新实例,新实例更新数据后也会生产对应上面语句的binlog;当data-sync中间件再次接收到binlog时,只要推断碰到tb_transaction表status=1的数据开始,后面的数据都直接舍弃不要,直到碰到status=0时,再陆续接收数据,以此来担保data-sync中间件只会流转业务诞生的消息。

数据校验模块由数据校验服务data-check模块来兑现,主要是基于数据库层面的数据对照,逐条核对每一个数据字段是否一致,不一致的话会通过配置的校验规章来进行重试或者报警。

通过数据校验,一旦发觉数据不一致,则需求对数据进行修复操作。

数据修复有两种案例,一种是适用于大范围的数据不一致,采纳重置kafkaoffset的方法,重新消费数据消息,将有问题的数据进行覆盖。

全局灰度案例:SP+用户纬度来兑现,SP纬度:凭仗灰度情境切量来做,用户纬度:依靠用户ID后四位百分比切流。

灰度切量的流程肯定要配合停写(秒级),为什么要停写,由于数据同步存在肯定拖延(正常毫秒级),而一切业务操作肯定要保障都在一个实例上,否则在旧库中业务刚刚调整了一条数据,此时切换到新库如果数据还没有同步过来就是旧数据会有数据一致问题。所以流程应该是:

虽然在切流之前,在测试情境进过了大量的测试,可是测试情境毕竟和生产情境不相同,生产情境数据库一旦出问题就也许是灭顶之灾,虽然上面介绍了数据校验和数据修复步骤,可是把问题拦截在发生之前是做服务稳定性最重大的工作。

因此我们提出了ABC验证的概念,灰度情境ABC验证预备:

详细灰度案例和数据源切换步骤:

整体数据迁移流程还是比较复杂的,时光也不是非常充裕(流程中还穿插着十一全链路压测改变),在有限的时光内集大家之力重复探讨发掘也许存在的问题,然后论证解决案例,不放过任何一个也许出现问题的环节,还是那句话,把问题拦截在发生之前是做服务稳定性最重大的工作。

流程中的细节还是非常多的,从数据迁移的预备工作到数据同步测试,从灰度步骤确定到正式生产切换,尤其是融合业务和数据的特色,有非常多需求考虑的细节,文中没有一一列出。

最终通过近两个月的紧张工作,无业务代码侵入、零事故、平稳地达成了扩分库分表和数据迁移的工作。

  • 热门标签

  • 相关产品 >

    福建云服务器

    适合个人入门

    福建云服务器

    适合中小企业

    广东云服务器

    适合个人入门

    北京云服务器

    适合个人入门

阿里云RDS分库分表扩容兑现平滑数据迁移

唯一小编 发布时间:2021-03-01 返回

2020年,笔者负责的一个高德打车弹外订单系统进行了一次扩分库分表和数据库迁移。该订单系统全局部署在阿里云上,服务应用阿里云ECS部署,数据库采纳阿里云RDS,配置中心基于阿里云ACM自研,数据同步基于阿里云DTS自研以及自研分库分表组件、分布式ID组件等等。

阿里云RDS分库分表扩容兑现平滑数据迁移

此次进行扩分库分表的背景是,原4实例4库、各个库64张表一共256张表,部分单表已超千万量级,按目前每日单量量级,一年内单表会达到上亿条记载,单表数据量过大会带来数据库性能问题。

4实例(16C/64G/3TSSD),4库(各个实例一个库),每库64张表,共256张表。

经过RDS后台一键诊断功能,来计算表空间应用情形(这里拿测试情境数据库举例)。

数据库的瓶颈主要表现在:磁盘、CPU、内存、互联网、联结数,而联结数主要是受CPU和内存作用。CPU和内存可以经过动态升配来提高,可是SSD磁盘容量最大支持到6T(32C以下最大3T、32C及以上最大6T)。

可是现阶段兼顾成本,可先将实例扩容一倍,采纳8个实例(16C/64G/3TSSD),各个实例建4个库(database)、各个库128张表(这里实质上是一个成本取舍的流程,理论上应该采取”多库少表”的准则,单库128张表其实太多了,单库建议32或64张表为宜)。

接下来如果实例压力提高可进行实例配置改进(16C/128G、32C/128G、32C/256G等);将来如出现单实例升配无法解决,在考虑扩容实例,只需求将database迁移至新实例,迁移成本较小。

按单表最多1000w条数据评估,4096张表可支持日5000w单3年(10.1压测标准)、日2000w单5年的架构。(因业务表比较多,此处忽略掉单条数据大小的计算流程)

32个库,各个库128张表。将来可最大扩容到32个实例,无需rehash,只需求迁移数据。

阿里云RDS规格和价钱一览

因扩分库分表涉及到rehash流程(256表变4096表),而阿里云DTS只支持同构库数据迁移,所以我们基于DTS的binlog转kafka实力自研了数据同步中间件。

整体数据迁移工作包含:前期预备、数据同步环节(历史数据全量同步、增量数据实时同步、rehash)、数据校验环节(全量校验、实时校验、校验规章配置)、数据修复工具等。

在进行数据同步前,需求先整理一切表的惟一业务ID,只有确定了惟一业务ID才学兑现数据的同步操作。

需求重视的是:

一旦表中没有惟一索引,就会在数据同步流程中造成数据重复的危险,所以我们先将没有惟一索引的表依据业务场景增加惟一索引(有也许是联合惟一索引)。

在这里顺便提一下,阿里云DTS做同构数据迁移,应用的是数据库自增ID做为惟一ID应用的,这种情形如果做双向同步,会造成数据覆盖的问题。解决案例也有,之前我们的做法是,新旧实物采纳自增ID单双号解决,担保新旧实例的自增ID不会出现冲突就行。由于这次我们应用的自研双向同步组件,这个难题这里不细聊。

分表规章不同决定着rehash和数据校验的不同。需逐个表整理是用户ID纬度分表还是非用户ID纬度分表、是否只分库不分表、是否不分库不分表等等。

数据同步全局案例见下图,数据同步基于binlog,独立的中间服务做同步,对业务代码无侵入。

后续对每一个环节进行介绍。

单独一个服务,应用游标的方法从旧库分批select数据,通过rehash后批量插入(batchinsert)到新库,此处需求配置jdbc联结串参数rewriteBatchedStatements=true才学使批处理操作生效。

另外特殊需求重视的是,历史数据也会存在不断的更新,如果先开启历史数据全量同步,则刚同步达成的数据有也许不是最新的。所以这里的做法是,先开启增量数据单向同步(从旧库到新库),此时只是开启积压kafka消息并不会真正消费;然后在开始历史数据全量同步,当历史全量数据同步达成后,在开启消费kafka消息进行增量数据同步(提升全量同步效率变少积压也是核心的一环),这样来担保迁移数据流程中的数据一致。

增量数据同步考虑到灰度切流稳定性、容灾和可回滚实力,采纳实时双向同步案例,切流流程中一旦新库出现稳定性问题或者新库出现数据一致问题,可迅速回滚切回旧库,担保数据库的稳定和数据稳妥。

增量数据实时同步采纳基于阿里云DTS的数据订阅自研数据同步组件data-sync兑现,主要案例是DTS数据订阅实力会自动将被订阅的数据库binlog转为kafka,data-sync组件订阅kafka消息、将消息进行过滤、合并、分组、rehash、拆表、批量insert/update,最后再上交offset等一系列操作,最终达成数据同步工作。

整体流程中有几个问题需求重视:

问题1:怎样预防因异步消息无顺序而致使的数据一致问题?

第一kafka异步消息是存在顺序问题的,可是要知道的是binlog是顺序的,所以dts在对具体进行kafka消息投递时也是顺序的,此处要做的就是一个库担保只有一个顾客就能保障数据的顺序问题、不会出现数据状态覆盖,从而解决数据一致问题。

问题2:是否会有丢消息问题,假如顾客服务重启等情形下?

这里没有采纳自动上交offset,而是每次消费数据最终入库达成后,将offset异步存到一个mysql表中,如果顾客服务重启宕机等,重启后从mysql拿到最新的offset开始消费。这样惟一的一个问题也许会出现瞬间部分消息重复消费,可是由于上面介绍的binlog是顺序的,所以能担保数据的最终一致。

问题3:update转insert会不会丢字段?

binlog是全字段发送,不会存在丢字段情形。

问题4:循环消息问题。

后面进行单独介绍。

前文有提到,由于是256表变4096表,所以数据每一条都需求通过一次rehash重新做分库分表的计算。

要说rehash,就必须先介绍下目前订单数据的分库分表策略,订单ID中冗余了用户ID的后四位,经过用户ID后四位做hash计算确定库号和表号。

数据同步流程中,从旧库到新库,需求拿到订单ID中的用户ID后四位模4096,确定数据在新库中的库表位置;从新库到旧库,则需求用用户ID后四位模256,确定数据在旧库中的库表位置。

想象一下,业务写一条数据到旧实例的一张表,于是诞生了一条binlog;data-sync中间件接到binlog后,将该记载写入到新实例,于是在新实例也诞生了一条binlog;此时data-sync中间件又接到了该binlog……不断循环,消息愈来愈多,数据顺序也被打乱。

怎样解决该问题呢?我们采纳数据染色案例,只要能够标识写入到数据库中的数据使data-sync中间件写入而非业务写入,当下次接收到该binlog数据的时候就不必进行再次消息流转。

所以data-sync中间件需求,各个数据库实例创建一个事务表,该事务表tb_transaction只有id、tablename、status、create_time、update_time几个字段,status默认为0。

再回到上面的问题,业务写一条数据到旧实例的一张表,于是诞生了一条binlog;data-sync中间件接到binlog后,如下操作:

此时data-sync中间件将上面这些语句打包全体上交到新实例,新实例更新数据后也会生产对应上面语句的binlog;当data-sync中间件再次接收到binlog时,只要推断碰到tb_transaction表status=1的数据开始,后面的数据都直接舍弃不要,直到碰到status=0时,再陆续接收数据,以此来担保data-sync中间件只会流转业务诞生的消息。

数据校验模块由数据校验服务data-check模块来兑现,主要是基于数据库层面的数据对照,逐条核对每一个数据字段是否一致,不一致的话会通过配置的校验规章来进行重试或者报警。

通过数据校验,一旦发觉数据不一致,则需求对数据进行修复操作。

数据修复有两种案例,一种是适用于大范围的数据不一致,采纳重置kafkaoffset的方法,重新消费数据消息,将有问题的数据进行覆盖。

全局灰度案例:SP+用户纬度来兑现,SP纬度:凭仗灰度情境切量来做,用户纬度:依靠用户ID后四位百分比切流。

灰度切量的流程肯定要配合停写(秒级),为什么要停写,由于数据同步存在肯定拖延(正常毫秒级),而一切业务操作肯定要保障都在一个实例上,否则在旧库中业务刚刚调整了一条数据,此时切换到新库如果数据还没有同步过来就是旧数据会有数据一致问题。所以流程应该是:

虽然在切流之前,在测试情境进过了大量的测试,可是测试情境毕竟和生产情境不相同,生产情境数据库一旦出问题就也许是灭顶之灾,虽然上面介绍了数据校验和数据修复步骤,可是把问题拦截在发生之前是做服务稳定性最重大的工作。

因此我们提出了ABC验证的概念,灰度情境ABC验证预备:

详细灰度案例和数据源切换步骤:

整体数据迁移流程还是比较复杂的,时光也不是非常充裕(流程中还穿插着十一全链路压测改变),在有限的时光内集大家之力重复探讨发掘也许存在的问题,然后论证解决案例,不放过任何一个也许出现问题的环节,还是那句话,把问题拦截在发生之前是做服务稳定性最重大的工作。

流程中的细节还是非常多的,从数据迁移的预备工作到数据同步测试,从灰度步骤确定到正式生产切换,尤其是融合业务和数据的特色,有非常多需求考虑的细节,文中没有一一列出。

最终通过近两个月的紧张工作,无业务代码侵入、零事故、平稳地达成了扩分库分表和数据迁移的工作。

©2016-2021 www.wcloud.cn All rights reserved.
唯一网络-数据中心、云网服务及数字化解决方案提供商©版权所有

免费预约

客户免费预约阿里云/唯云架构师上门服务。免费服务内容:云数据中心、网络安全、云专线、云等保、公有云、混合云和其它云协助迁移。

请保持电话畅通,我们将在工作时间与您电话联系。

立即预约