数据迁移基础:原则与策略

做数据迁移这事儿,跟搬家很像。你总得先理清楚:哪些东西必须带走,路上不能摔碎,到了新地方还得能正常工作。我做了几年密钥迁移工具,踩过的坑都能开杂货铺了。今天就跟你聊聊数据迁移的两大支柱——原则和策略。

先别急着上手写代码。咱们得先统一思想,不然后面审计的时候,有你头疼的。

数据迁移的三条铁律

我个人习惯,把迁移原则总结成三个关键词:不丢、不乱、不吭。说白了就是完整性、一致性、可用性。

原则核心要求我的避坑笔记
完整性源端所有密钥数据都要迁移到目标端,一条都不能少我曾经遇到过因超时导致某张表只迁移了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设计,那才真正开始动手干活。今天先把这些概念消化透,后面用得上。