数据迁移基础:原则与策略
做数据迁移这事儿,跟搬家很像。你总得先理清楚:哪些东西必须带走,路上不能摔碎,到了新地方还得能正常工作。我做了几年密钥迁移工具,踩过的坑都能开杂货铺了。今天就跟你聊聊数据迁移的两大支柱——原则和策略。
先别急着上手写代码。咱们得先统一思想,不然后面审计的时候,有你头疼的。
数据迁移的三条铁律
我个人习惯,把迁移原则总结成三个关键词:不丢、不乱、不吭。说白了就是完整性、一致性、可用性。
| 原则 | 核心要求 | 我的避坑笔记 |
|---|---|---|
| 完整性 | 源端所有密钥数据都要迁移到目标端,一条都不能少 | 我曾经遇到过因超时导致某张表只迁移了90%,审计时差点翻车 |
| 一致性 | 迁移前后数据要保持逻辑等价,存量不冲突 | 密钥的版本号、失效时间这些字段,容易在格式转化时出幺蛾子 |
| 可用性 | 迁移完成后,业务系统要能用新密钥正常加解密 | 有一次迁移完忘了刷新密钥缓存,生产直接报错 |
完整性检查是底线。我建议你在迁移结束后,至少做一次全量校对。比如用MD5比对源和目标的密钥总条数,再用随机抽样验证100条数据的每个字段。
你想想看,如果一致性出了问题,存量密钥可能在新环境里解不出来老数据,那可就真成“死锁”了。所以这三个原则,一个都不能少。
迁移策略:在线 vs 离线
选哪种策略,取决于你的业务能不能停。我见过最野的方案是直接停服两天,差点被业务部门追着打。来,看看两者的核心区别。
离线迁移
先把源密钥导出成一个文件(比如加密的CSV或SQL dump),再导入目标系统。这种方式最简单,适合你的系统可以接受几小时甚至一天的中断。
- 优势:操作简单,逻辑清晰,很少出现脏数据。
- 劣势:迁移期间业务不可用,密钥更新有窗口期。
- 适用场景:存量数据一次性搬迁,后续不再双向同步。
我刚开始做迁移时,就喜欢用离线方式。有一次导出时忘记切只读模式,结果业务同时还往里写数据,导出的文件里既有老数据又有新数据,乱成一锅粥。嗯,这里要注意,离线迁移前一定要冻结源端的写入操作。
在线迁移
源和目标系统同时运行,通过数据同步工具(比如CDC或者双写机制)把变更实时同步过去。迁移完成后,再优雅地切换。
- 优势:业务几乎无感知,迁移时间窗口可控。
- 劣势:技术复杂度高,需要处理一致性冲突和同步延迟。
- 适用场景:对可用性要求高的支付、认证等核心系统。
在线迁移最关键的是切流那一刻。我记得有一次做了双写,但切流脚本里有个bug,导致部分流量回源端,密钥出现了“分裂”。最后查了一天,才发现是负载均衡的cookie没处理好。
千万不要在生产环境第一次做在线迁移。我建议你至少先在预发布环境演习两次,把切流脚本、回滚方案、监控指标都跑熟了,才敢上生产。
策略对比表
为了方便你快速决策,我做了一个对照表。你拿起来就能用。
| 对比维度 | 离线迁移 | 在线迁移 |
|---|---|---|
| 迁移窗口 | 数小时~数天(业务中断) | 分钟级(几乎无感) |
| 数据一致性 | 容易保证(一次性快照) | 需要实时校对(有冲突风险) |
| 技术复杂度 | 低(导出/导入脚本即可) | 高(需要CDC、同步队列、切流组件) |
| 回滚难度 | 低(恢复快照即可) | 高(需要断开同步、回写数据) |
| 审计友好度 | 高(有完整单次记录) | 中等(需要额外记录增量同步日志) |
我个人更推荐混合策略。比如先做一次全量离线迁移,然后开启增量在线同步,最后在周六凌晨做一次短窗口切流。这样既有离线迁移的可靠性,又有在线迁移的低中断。我在多个项目中都用这个方案,目前没出过岔子。
核心知识体系
下面这张图,把刚才讲的原则和策略串起来了。你可以把它当成做迁移方案时的检查清单。
简单的一行代码:校验一致性
别觉得高大上,其实校验逻辑可以很朴素。下面这个函数,是我项目中常用来做一致性检查的骨架。它不花哨,但够用。
def check_consistency(source_db, target_db, key_table):
source_count = source_db.count(key_table)
target_count = target_db.count(key_table)
if source_count != target_count:
print(f"[严重] 密钥总数不一致: 源={source_count}, 目标={target_count}")
return False
# 随机抽100条,逐字段比对
sample_keys = source_db.sample(key_table, 100)
for key in sample_keys:
target_key = target_db.get(key_table, key.id)
if key != target_key:
print(f"[错误] 密钥 {key.id} 数据不一致")
return False
print("[通过] 一致性检查完成,没问题")
return True
一个小技巧:在实际项目中,你可以把抽样比例提高到5%,或者用分桶对比。我曾经用这个函数帮团队在一次线上迁移中抓到了3条因为编码问题导致数据错位的记录。嗯,有时候简单的东西反而最管用。
好了,关于数据迁移的原则和策略,就聊到这儿。你大概心里有数了:迁移不是简单地把文件从A复制到B,而是要保证完整、一致、可用。至于选在线还是离线,关键看你业务能不能等。下次咱们聊具体的迁移工具和SDK设计,那才真正开始动手干活。今天先把这些概念消化透,后面用得上。