0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

分享一次海量数据平滑迁移实战

京东云 来源:jf_75140285 作者:jf_75140285 2024-07-03 16:33 次阅读

背景

采购系统(BIP)在经历多年演进后,系统整体复杂度和数据量俨然已经极具规模,本文着重讨论海量数据的治理

存储现状:工程端实时订单库采用MySQL 5.5集群,其中主库配置为32C/48G/6000G,无法归档的订单热数据占磁盘空间85%(5.1T)

痛点:6T磁盘已经单容器最大,无法继续扩容,剩余磁盘余量过小,难适应未来发展

目标

降低磁盘容量,优化数据模型,提升系统稳定性

调研

首先,既然是要解决存储容量的问题,就要对详细的容量情况有个更加清楚的了解。总结下当前存储容量问题,最大的表是订单操作日志表lifecycle共1.3T,大于500G的表2张共1.5T;100G~500G的表10张共2.6T。以下是优化前库里大表(大于100G)的详细空间占用情况:

序号 表名 空间大小(行数|总大小|数据大小|索引大小)
1 lifecycle 46亿 | 1.3T | 856G | 328G
2 cgfenpei 5.8亿 | 665G | 518G | 147G
3 cgtable 5.8亿 | 491G | 287G | 204G
4 cgdetail 5.5亿 | 405G | 308G | 97G
5 po_asn_receipt_detail 4.5亿 | 351G |167G | 184G
6 po_data 2.5亿 | 321G | 312G | 9G
7 purchase_order_extension 4.2亿 | 293G | 166G | 127G
8 po_stock_detail 7.3亿 | 204G | 104G | 100G
9 po_channel 6.1亿 | 191G | 70G | 121G
10 cgtablesubtable 6亿 | 154G | 62G | 92G
11 unduprecord 4.2亿 | 138G | 138G | 0G
12 po_stock 2.8亿 | 126G | 63G | 63G

合计 4.6T

其次,确认当前最高效的优化思路是将lifecycle表迁移到其他库,原因有二:1.lifecycle表的含义是操作日志,在业务上不算订单域内最核心的模型,风险可控;2.占用空间大,单表46亿行数据,空间占用1.3T,一张表占了磁盘空间的22%,优化的ROI高

最后,想说明下,为什么没有直接将整个库,从传统MySQL切换到JED,原因也有二:1.JED和MySQL的查询语法还是有一定差异,直接切换,成本和风险极高;2.切换存储中间件,获取分布式架构下更大的存储空间并不是银弹,理智告诉我们要结合系统现状,不可盲目下定论

挑战

保障海量数据(存量46亿行,增量600w+行/天,TPS峰值:500+,QPS峰值:200+)迁移期间读、写稳定和准确。需要补充一下:lifecycle虽然不算订单最核心业务模型,但依旧是辅助业务决策的关键数据,也非常重要

例子:

wKgZomaFDL-AOm55AAEYz3r4oPI090.png

方案

整体方案

数据同步 -> 双读 -> 双写 -> 离线验证 -> 数据清理

wKgZomaFDMCASkqxAAj6Pwvr8eo749.png

详细设计

数据同步,通过DRC实现,历史全量+增量,其中有以下几点使用心得:

◦同步速度问题,本次是使用传统MySQL5.5 -> JED 底层MySQL 8.0 单表同步,效率大概是4M/S,一共花了3天半左右

◦数据同步过程中不要操作暂停,否则任务重启后,会重新同步历史数据,导致数据同步周期变长。详情参考: 关于全量任务暂停重启之后数据同步慢的原因

◦字段兼容问题,老库历史时间字段类型是datetime,新库需要改为datetime(3),这种数据同步是可以兼容的(下文会讲为什么要优化时间字段精度)

◦数据验证问题,当时在历史数据全量同步完毕后开启了DRC数据验证,但是许久未执行完成,收到DRC运维告知出现大量报错,最终结论是暂时不支持这两个版本的数据比对(5.5->8.0),这也是为什么整体架构上采用BDP抽数比对数据的主要原因

数据验证,业务程序完成双写、双读改造

双写

wKgZomaFDMGAfjFxAAN0PJcumXw761.png

为什么采用双写?答:控制风险。1.团队内还没有应用直接写入多分片JED的先例,而且新、老库的底层MySQL版本也差异比较大(5.5 vs 8.0),当时通过分批次灰度上线完成逐步切量验证;2.方便进行数据验证,lifecycle是业务操作日志,基本涵盖了所有的写入场景,其中因为历史问题,不乏一部分逻辑和订单更新在同一事务中,现在迁移到新库,本地事务会存在不生效的场景

▪具体改造方案:

新增【验证开关】,开启后新/老库双写,另外需要要引入vitess驱动,目前只支持JDK8及以上

新增【上线开关】,开启后只写新库,此开关是在验证逻辑无问题后,最终切换的开关,代表迁移完成

▪注意,开关改造完成上线后,“全量+增量DRC任务”在验证期间是一直启用的,也就是说验证期间,增量数据会写两份到新库

▪一部分是实际的生产数据,一部分是待验证的测试数据。那么就带来另一个问题,如何识别和区分这两部分数据,我们采用的方案是:JED建表指定趋势自增的最小id(200亿)+【验证开关】开启的时间戳进行区分

▪如下图,其中A和A'都是【验证开关】切换后的增量数据,由于老库的id已经自增写到了70亿,并且DRC同步任务也是指定id写入,所以建表时指定新增数据id是200亿(详情参考: 数据库自增ID列设置 ),和老数据之间存在一定gap方便识别。BDP脚本数据比对的也是:老库.A和新库.A'(这里默认DRC增量同步的数据是准确的)

▪清除测试数据,真正完成【上线开关】切换,需要提前清除测试数据,只需指定id>200亿的物理删除即可。注意:针对多分片的JED物理删除delete语句,我们程序上如果为了防止大事务,而采用“for循环+limit n”的方式执行,实际的每次SQL语句执行结果是多个分片的n的聚合,而不是n,如果程序上对结果有判断逻辑,需要额外注意

wKgaomaFDMGAY5rGAAOA-LF7I_U880.png

双读

wKgZomaFDMKAMNWiAATOmQl2_C8531.png

整体逻辑基本复用写入期间已有开关,其中针对新库当中DRC实时同步的数据(上图:新库.A)会根据开关开启时间进行过滤

▪其中,在验证期间,新、老库都会根据采购单号进行查询并实际返回老库的查询结果,其中还会进行结果比对,出现数据不一致会输出异常日志关键字

▪另外,因为lifecycle操作日志数据是有先后顺序的,老库的处理方式是根据自增id进行倒排,到了新库以后,由于采用的是JED分片(分布式存储的磁盘空间更大),考虑到开发成本,数据id采用的是趋势递增的自增主键(详情参考: Vitess全局唯一ID生成的实现方案 ),这时多集群并行写入无法继续使用基于id倒排的方式返回结果(后写入的数据可能id较小,可以参考sequece发号器的ID生成),所以将原始的数据写入时间戳从datetime提高精度到datetime(3),通过数据写入时间进行倒排,这里也解释了上文,新库DRC数据同步为什么要考虑字段兼容的问题

▪补充1:这里基于时间倒排在业务上是准确的,因为lifecycle数据是根据订单号进行分片的,所以同一订单一定落在单分片上,也就是说不存在不同分片时钟偏移的问题,单订单的操作日志的时间序列一定是按照写入顺序逐渐增加的

▪补充2:新库字段类型变更(datetime->datetime(3)),32分片,共46亿行数据,执行了大概1小时,期间主从延迟最高30分钟,容器负载正常

▪补充3:应用的关键字告警配置,日志文件仅支持以error.log、err.log、exception.log结尾,并开启历史日志的路径

▪最后,双读期间共通过业务的实际查询流量发现数据不一致问题2个+,在并未影响到业务使用的前提下及时发现了系统异常

离线验证

▪lifecycle归根结底还是写多读少的业务场景,为了防止出现上文数据比对验证的遗漏,我们会采用BDP离线任务会分别开启增量数据+历史全量数据验证。通过对新、老库的全量数据字段相互sql inner join的方式完成比对,其中会忽略id和写入时间,因为新库的id不是单调递增、时间精确到了毫秒。期间共发现有效数据问题3个+,均是因为本地事务回滚导致的数据不一致的场景

收尾工作

◦完成【上线开关】切换,只读、写新库,完成整体平滑迁移。在无QA参与前提下,验证期间未出现过数据丢失、重复、错误等异常

◦切换完成后,老库老表和DRC同步任务依旧保留了一周的时间,防止出现场景遗漏,产生数据丢失

◦46亿行大表清理,采用drop+create的方式实现效率、稳定性更高,在业务低峰期完成脚本执行,大概花费10秒的时间,容器负载、内存等指标正常。但是当时碰上了DBA的备份任务,导致有一个从库主从延迟升高,这个后续需要注意

审核编辑 黄宇

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 数据
    +关注

    关注

    8

    文章

    6904

    浏览量

    88845
  • 存储
    +关注

    关注

    13

    文章

    4266

    浏览量

    85680
  • 迁移
    +关注

    关注

    0

    文章

    33

    浏览量

    7919
收藏 人收藏

    评论

    相关推荐

    MySQL数据迁移的流程介绍

    本文介绍了一次 MySQL 数据迁移的流程,通过方案选型、业务改造、双写迁移最终实现了亿级数据迁移
    的头像 发表于 11-25 09:20 78次阅读
    MySQL<b class='flag-5'>数据</b><b class='flag-5'>迁移</b>的流程介绍

    一次电源与二电源有什么不同

    在电力系统和电子设备的供电领域中,一次电源与二电源是两个至关重要的概念。它们各自承担着不同的功能和角色,共同确保电力供应的稳定性和可靠性。本文将对一次电源与二电源的定义、区别以及它
    的头像 发表于 10-10 14:10 1236次阅读

    一次电池分类以及应用场景详解

    01 一次电池简介 一次电池即原电池(primarycell、primarybattery)(俗称干电池),是放电后不能再充电使其复原的电池,通电电池有正极、负极电解以及容器和隔膜等组成。 一次电池
    的头像 发表于 09-30 17:52 463次阅读
    <b class='flag-5'>一次</b>电池分类以及应用场景详解

    labview如何做到一次触发采集一次

    最近在做个电压测试模块,要求是在个时间段内,出现个上升沿触发采集,并且只采集一次,采集次数为出现上升沿的次数,采集时间,采样率及单
    发表于 08-07 10:16

    一次消谐器的构造

    今天来给大家介绍一下一次消谐器的构造。 一次消谐器是种用于消除电力系统中的谐波及无功功率的装置,它由感性元件和电容器构成,感性元件用于吸收系统中的无功功率,而电容器则用于补偿系统中的感性无功功率
    的头像 发表于 05-30 14:55 374次阅读

    鸿蒙OS开发:典型页面场景【一次开发,多端部署】实战(设置典型页面)

    本示例展示了设置应用的典型页面,其在小窗口和大窗口有不同的显示效果,体现一次开发、多端部署的能力。
    的头像 发表于 05-27 09:36 1101次阅读
    鸿蒙OS开发:典型页面场景【<b class='flag-5'>一次</b>开发,多端部署】<b class='flag-5'>实战</b>(设置典型页面)

    拒绝无效尝试,EMC问题解决实战教学带你一次性解决问题!

    EMC实战教学SES2024.06.06辐射发射、传导发射、ESD、EFT、CS、浪涌等几个项目是产品电磁兼容测试中的常见问题,也是困扰广大工程师朋友的整改定位分析难题;在这种时刻,如有通过实战直播
    的头像 发表于 05-24 08:17 325次阅读
    拒绝无效尝试,EMC问题解决<b class='flag-5'>实战</b>教学带你<b class='flag-5'>一次</b>性解决问题!

    stm32f030的AD转换,如何调用一次getadcvalue() 就采集一次数据

    通道单转换吗? 目的:调用一次getadcvalue()就采集一次数据 求大神指点,while(EOC)不注释掉的话,好像只能调用一次,手册上写,EOC不是读取
    发表于 05-13 07:48

    STM32F429如何一次传3000个数据

    正点原子的历程中实用的是8位的数据传输,也就是说最多一次能传255个数据,我要是一次想传3000个数据,应该怎么更给程序?
    发表于 05-11 08:56

    配置SPI一次收发个16位数据,但抓的数据波形显示,数据连续发送和接收了4为什么?

    我配置SPI一次收发个16位数据,但抓的数据波形显示,数据连续发送和接收了4,这个情况有碰到
    发表于 04-18 07:52

    基波是一次谐波么 基波与一次谐波的区别

    基波是一次谐波么 基波与一次谐波的区别  基波和一次谐波是两个不同的概念。 基波是在谐波分析中指的是频率最低且没有任何谐波成分的波形,它是构成复杂波形的基础。在正弦波中,基波就是正弦波的本身。基波
    的头像 发表于 04-08 17:11 6581次阅读

    电力系统一次设备和二设备区别,二回路的分类

    在电力系统中,一次设备是指直接参与电能生产、传输和分配的电气设备,如发电机、变压器、电力电缆等。电力二设备是指对电力系统一次设备进行监视、测量、控制、调节和保护的辅助设备,不直接与电能主电路连接
    的头像 发表于 01-19 10:10 2539次阅读
    电力系统<b class='flag-5'>一次</b>设备和二<b class='flag-5'>次</b>设备区别,二<b class='flag-5'>次</b>回路的分类

    ADUCM360怎样才能实现AD每0.2秒采集一次数据

    ADUCM360怎样才能实现AD每0.2秒采集一次数据?用定时器每0.2秒中断一次,在定时器中断中开始AD单转换一次,可以吗? void GP_Tmr0_Int_Handler(v
    发表于 01-12 06:34

    一次消谐和二消谐有什么区别

    一次消谐和二消谐是在交流电电路中进行的两种储能元件的选择,旨在改善电流和电压的波动问题。下面将详细介绍一次消谐和二消谐的区别。 一次消谐
    的头像 发表于 12-20 14:48 1613次阅读

    如何只写一次数据就让AD5421的输出电流保持住?

    请问大虾: 现象:连续写AD5421的数据寄存器,可以使AD5421输出电流保持住。但是只写一次数据寄存器,AD5421的输出电流无法保持,但是读数据寄存器时,寄存器的值是写进去的值。 问题:如何只写
    发表于 12-19 08:24