在 IM 服务化架构中,IM 的核心业务(比如:登录、收发消息、状态同步、未读数等等)的实现逻辑与在分层架构 IM 系统中实现逻辑高度类似;本质上,服务化架构就是分层架构,只是在垂直方向上有更细的切分粒度。
今天聊一个常见的业务操作 — 数据迁移。
一个业务系统从单体逐步演进到服务化,其数据量一般都会很大,在系统迭代的过程中,经常会发生数据存储方式的变化,比如:从单表拆分成256张表(分表),从单库拆分成8个库(分库),从 MySQL 数据库更换成 TiDB 数据库,此时就会面临着 ”数据迁移“ 的业务操作。
对于大数据量的数据迁移,是一个非常大的系统工程,出现任何错误都会影响用户的体验;对于数据迁移需要满足三个基础要求:
- 平滑迁移:即数据迁移过程,系统继续提供服务,中间不停机,用户无感知;
- 随时回滚:即数据迁移的过程中,在任何一个环节出现问题时,都可以随时回滚到最初状态,不影响用户;
- 数据最终一致:即数据迁移之前和数据迁移之后,数据最终是一致的,不能因为迁移造成数据的不一致。
我们在服务化架构的 IM 系统中,有两次完整的数据迁移实践,一次是将关系型数据库 MySQL 成功替换成 NewSQL 数据库 TiDB,一次是将联系人单表拆分成了 256 张表;对这两次数据迁移流程进行分析和抽象,总结出了一套方便落地的普适的数据迁移流程,可以适用在其他的业务场景中,如下图。
普适的数据迁移流程,包括四步:
- 数据库同步即基于数据库本身的 “主从同步” 能力,实现从源库到目标库的数据全量同步的目的;同时,logic 服务不断向源库写入的数据,也会基于数据库的 “主从同步” 能力将增量数据同步到目标库。
- 数据双写增量数据同步的效果不能一直借助于 “主从同步” 的能力,所以 logic 在将数据写入源库的同时,借助于 MQ 将写入源库的新数据通知到 extlogic 服务,由 extlogic 实现对目标库的数据写入,同时切断源库到目标库的 “主从同步”;这里注意,extlogic 写入目标库后,再切断 “主从同步”,这里会发生主键冲突的错误,但不会丢数据。
- 灰度读通过第2步实现了数据双写,源库和目标库的数据是最终一致的;这一步由 logic 开始对目标库进行灰度读,以验证目标库中数据的准确性;灰度读是一个循序渐进的过程,比如 logic 有 99% 的读流量发送给源库,有 1% 的读流量发送给目标库,持续1~3天后,再增加读目标库的流量占比。
- 全量读写对目标库的灰度读是一个持续的过程,当对目标库的读流量达到 100% 后,logic 可以切断对源库的数据写入,此时目标库完全承担了全量的业务读写;最后将 logic 和 extlogic 代码合并即可,这就是服务代码的范畴了,目标库已经成功替代了源库。
这个数据迁移的流程,有两个核心思想:一是先通过数据双写的方式,实现对目标库地写;二是通过灰度策略,实现对目标库的读。整个流程,完全是平滑迁移,对用户无感知,任何一个环节出现问题都可以随时回滚到最初状态。
上述数据迁移流程,有几个点需要特别注意:
- 该数据迁移流程不适用于数据强一致性的场景,即刚成功写入到库中的数据,就需要立刻读出来,这样的场景不适合;毕竟,写入到源库的数据,同步到目标库是需要时间的。
- 数据双写时,为什么需要 MQ 来辅助呢?由 logic 通过 RPC 调用 extlogic 是否可行呢?MQ 具有更高的稳定性,extlogic 写入目标库失败后,消息仍然会存在 MQ 中不会丢失。
- 在上述流程中,logic 写源库和 logic 写MQ 是需要保证同时成功的,即实现原子性,此时可以借助于 MQ 的事务消息来实现;在严格情况下,用事务消息是最好的,在并不十分严格的场景下(与钱无关),用普通的 MQ 也可以满足需求。
- 在对同一条数据有并发更新的场景中,需要借助于顺序消息来实现,以保证数据的准确性;例如源库中存在一条数据 x=3,logic 有两条并发更新的请求(x=5 和 x=7)写入源库,那么就需要借助于顺序消息,以保证 extlogic 服务按 x=5 和 x=7 的顺序写入目标库。
最后,总结文中关键:
- 数据迁移需要满足三个基础要求:平滑迁移、随时回滚、数据最终一致;
- 普适的数据迁移,包括四步:数据库同步、数据双写、灰度读、全量读写;
- 数据迁移流程有两个核心思想:一是数据双写实现“写“”;二是灰度策略实现“读”;
- 数据迁移流程注意点:不适合强一致性场景,严格情况下用事务消息,特殊情况下用顺序消息。
思考一下:套用上述流程,如何实现 IM 联系人表的分表操作(由单表扩容成128张表)?
作者:棕生
来源:架构之魂
原文:https://mp.weixin.qq.com/s/3CMZJOXlHgEG4rCAadflSw
版权声明:本文内容转自互联网,本文观点仅代表作者本人。本站仅提供信息存储空间服务,所有权归原作者所有。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至1393616908@qq.com 举报,一经查实,本站将立刻删除。