互联网服务线上数据迁移的原则和方法

互联网业务变更非常快,随着业务规模扩大,线上的业务也会涉及重构和迁移。比较难的就是存储迁移,可能从前的存储不适合新的业务模型了,例如从关系型数据库迁移到nosql,或者数据的存储格式发生了巨大的变化。

为什么说涉及数据迁移的业务最难呢?因为数据是有状态的,不像逻辑和接入层,方便灰度,即使出问题马上回滚就能恢复(如果涉及写数据也也有问题)。然而数据是有状态的,如果切换后发现新的写存储数据有问题,是很难修复的,也很难发现的。

任何迁移或更新,涉及到数据的,都有一个原则:要有验证比对和回滚能力。

验证比对

数据迁移后,要有办法验证这次迁移是成功的,没问题的。只是从代码上说,看,前后逻辑都一样,肯定没问题是靠不住的。我们要从结果,从用户的角度来验证,查看新老数据是否一致,是否有问题。

一般的方法是双写。老的数据库还对外服务,把写操作同步一份给新数据库,两个库一起写。把有改动的用户数据同步过来,然后再写一个同步程序,把所有用户的全量数据导过来。检测程序,能够根据每个key进行比对,定期把库里所有的数据进行新老比对,当比对率达到阈值以后。还要做一个数据比对层,用户读写的时候先走比对层,同时给新老两个逻辑层同步包,也接收回包。然后把回包进行二进制比对,保证返回给用户的数据也是一致的。

当都达到一致之后,就可以切换了,切换后以新层为主,老层为辅,也接收同步数据。

回滚数据能力

为什么验证比对里最后老层还要接收新层的同步呢,直接切换不好吗?是因为万一切换后出现bug,发现其他地方有问题,可以马上回滚回老数据。保证线上服务正常,给开发修复bug留下充足的时间,不会有很大的时间压力。如果不能马上回滚,只能在线修bug。后续的每次发布修改,对开发的个人能力和状态依赖大,不可控因素太多。很难保证服务质量。

再多说一下,由于是重构,有时会发现从前数据里的错数据,或逻辑bug。不建议马上修复,新的要先和老的逻辑数据对齐,稳定后再修复老bug。否则bug改完后就没有一个标杆来验证数据是否一致了。

有人会说,弄这么多,得多久能完成迁移啊,效率太低。考试题目做的再快,不对也是白搭,之所以做这么多,就是保证万无一失。欲速则不达,如果数据错了再去修补,时间花费的更多,而且有时是补不回来的,只能回档,那时给用户造成的损失就大了。在QQ后台,每次数据迁移都要经过几周的发布比对才能切换,重大的数据层重构,没个一年半载达到六个9的一致性,根本不会切换的。这也是为什么一次次在行动的火车上换发动机能够成功的原因!

总结

涉及到数据的变更发布,要有比对能力,有从结果出发的方法,能够验证数据迁移后是正常的才可以。只从代码逻辑层面分析是不靠谱的。

要有plan B,如果真的有问题,要能够回滚,有回旋的余地。

做到以上所说,才能立于平滑迁移数据服务的不败之地!