4亿表数据库集群迁移方案实践
4亿表数据库集群迁移方案实践
背景
“营销自动化”功能数据体量大、QPS 高,数据库资源占用一直备受争议。最近,决定将该功能从混用数据库集群迁移出去,目标集群是某云厂商“分布式数据库(MYSQL)”,迁移原因有下面2个
-
业务高峰期和其它业务抢占资源,相当强势,造成其它业务高延迟、数据异常等。迁移后避免影响其它业务;
-
原本期望该业务放手大干现在畏首畏尾,迁移后可以进一步提高系统并发,打满数据库资源跑,资源不足时动态扩容/缩容最大化利用硬件资源。
数据库集群迁移,很早萌生想法了,数据量在2亿左右时简单验证了方案可行性,当时同步了一部分数据,通过线上复杂SQL验证,性能是满足的;后来出于成本考虑、长期SQL调优性能问题不明显搁置了。近期数据量激增,也为了适应未来数据体量增加该方案被重新提上日程。
风险评估
为了保证项目成功,联合基建团队做了全方位评估
数据库选型
优先考虑稳定性、可用性、安全性、自动弹性扩缩容、就近访问、低网络延时等。不详细赘述。
资源评估
为了降低迁移中风险保证迁移成功,针对“表数据体量”、“表读写QPS”、“SQL复杂度”、“迁移复杂度”、“跨团队协同复杂度”等维度进行评估。
数据体量评估
经过对业务盘点(平时开发文档比较完善不用花费太多时间)业务表11张,分别统计了数据体量,亿级别表3张,数据体量最大表在4亿左右。业务成熟,涉及表多,为了降低迁移风险沟通后决定采用“多次分批迁移“策略,第一步迁移数据体量最大的表,若大表迁移成功并无性能问题,小表迁移就简单了。
虽然业务表多,但是操作单一简单,SQL都是单表操作不存在关联查询,这也大大降低了迁移复杂度。
QPS 评估
新集群动态扩容可快速扩容读节点并且无需数据复制,写节点扩容比较麻烦。所以按照读写分别统计qps。
以最近7天业务高峰期某一段时间,读 SQL qps 最高 3215 qps/s,qps 是相当高了,如下图:
以最近7天业务高峰期某一段时间,写 SQL qps 最高 618 qps/s,不算太高,如下图:
SQL 复杂度评估
从SQL看板看出99.99%SQL,性能非常好500ms内数拿到结果,也有一些突刺在5s甚至10s左右,这部分SQL主要是统计SQL,count+group by 组合。验证SQL性能我们模拟这部分SQL为主,性能问题验证相对简单了。
迁移复杂度评估
本次迁移非常复杂,主要围绕新集群性能、迁移后数据完整性、业务方是否停服、回滚、数据双写等风险。
新集群性能验证方案
首先,全量同步线上数据至新集群,用线上慢SQL初步验证SQL性能,如果第一步性能不满足迁移集群就不用干了。
数据完整性和停服迁移方案
全量数据+增量数据同步过程中,若业务方切换集群可能导致数据不一致情况,比如:老集群insert数据,业务应用切换数据库集群,update同一条数据,迁移工具同步延迟导致数据更新失败数据异常。
运维同学建议在准备切换数据库流量时短暂停服,停服对大部分业务是不可接受的;停服还有一个缺点,迁移必须在业务低峰期,从数据表操作统计分析并不具备业务低峰期(定时任务更新频繁),所以停服方案放弃。
回滚方案
全量切换后若性能不满足预期,为了不影响客户使用,立刻切回原集群。新集群产生数据同步至原集群保证数据完整性,方案太复杂了。
数据双写方案
经过多轮讨论最终决定以数据双写解决回滚、数据完整性等问题。业务方改造代码实现数据双写能力,双写能力上线前存量数据已通过ETL工具已同步至新集群,上线后立刻停止ETL增量同步管道。双写有以下好处:
-
验证新集群数据写入性能,假设写入性能不满足回滚双写或充钱买硬件,不影响业务;
-
采用双写机制,有两份数据,读流量可任意切换,回滚方案更轻量,通过改配置路由新老集群;
-
采用双写机制,数据完整性不用复杂方案保证,双写上线后立刻停掉ETL增量同步管道,如果担心数据一致性问题,将发布这段时间内的更新/插入数据从老集群同步至新集群覆盖新集群数据。
双写方案引入了另一个问题,老集群写入成功新集群写入失败如何解决?
新集群写入增加重试机制,重试3次任然失败,失败操作写入日志系统并且本次写入不影响线上业务。若发现有写新集群失败操作,通过人工补救或者自动化工具补救即可(评估下来概率非常低)。
跨团队协同评估
为了减少团队协同成本,本次数据迁移业务团队包括我在内2名,运维团队3名。
迁移方案
业务调整
-
服务内新增“新集群”数据库相关配置;
-
改造repo(dao)层代码支持新老集群双写;
a. 新库写入增加重试机制
b. 重试后新库任写入失败则打印日志,并且不要影响线上业务流程,事后需要手动处理新集群数据(概率低)。
-
repo(dao)层支持开关配置,通过配置切换“读流量”。
数据库分区
保证同老集群分区方案一致,业务方改动最小。
迁移步骤
-
准备新集群;
-
建表+建索引;
-
ETL 全量同步历史数据;
-
新集群新慢 SQL 验证性能,性能符合预期再改代码;
-
业务方改造代码,双写、数据库配置、支持开关切流;
-
代码全量后验证新集群写入性能,双写上线立刻关闭ETL从老集群同步数据至新集群管道;
-
打开“流量切换开关”,按租户读流量切换;
-
持续观察1周左右,全量切换;
-
全量一周内监控、看板常规化巡检。
-
半个月内关闭双写机制。
监控设计
防止迁移后造成大量客户不可用,监控、告警比不可少,一定要在客户感知前发现和解决问题。本次迁移是数据库集群,监控主要围绕数据库铺开。
-
SQL看板,方便查看SQL总量、慢SQL总量、SQL耗时情况等;
-
慢SQL告警,定义超过5s为慢SQL,如果告警频繁说明性能不及预期,通过索引、改造SQL快速优化,不能快速处理考虑回滚;
放量设计
数据库集群迁移对上层业务影响巨大,需要非常谨慎,尤其是对头部租户搞不好客户业务异常后导致客诉和赔偿,采用平滑方案逐步放量,稳定后再全量开放。
-
数据双写方案通过内灰、外灰、全量策略即可,双写对业务并不影响;
-
读流量qps较高,通过配置切流,如果性能不及预期可以快速切换,对客户造成影响小。
回滚设计
-
若新集群写入性能不符合预期回滚双写代码,不影响线上业务;
-
数据双写期间,读流量切换可通过修改配置回滚;
-
数据双写通道关闭后,不支持回滚。
总结
-
复杂的业务加上大体量业务表,数据库集群迁移非常复杂,往往很难提前预估。如果避免不了数据迁移,一定要尽快决策,业务渗透率、数据体量对迁移方案复杂度影响都非常大;
-
任何方案都无法完全保证数据一致性,一定范围误差是可以接受的,如果出现一致性问题能通过日志手段重放补偿数据。
转载自:https://juejin.cn/post/7395593543962837031