查看原文
其他

程序员必备,《新老系统切换宝典》

Zachary 跨界架构师 2022-09-10

这里是Z哥的个人公众号

每周五11:45 按时送达

当然了,也会时不时加个餐~

我的第「216」篇原创敬上



大家好,我是Z哥。

有三周没有发文了,有点过意不去~

不过最近的辛苦也没有白费,总算完成了一个小里程碑,目前负责的项目中难啃的两块骨头总算啃掉了一块,松了半口气。

也顺带松口气腾出时间来写点东西。


最近正在做新老系统切换的准备工作,对于新老系统的切换方案,正好最近有做一些了解和思考,在这里和大家分享一下,可能你以后也会用得到。


除非你所在的企业是一个发展没多久的企业,否则新老系统的切换其实是个很常见的问题。我认为大家都有必要掌握这方面的知识。

可能有些人会觉得,这不是很简单么。找个半夜的时间,关闭系统的对外访问,然后一顿发布,不就完成切换了么。

这个方案也不是不可行,只是对外部条件的要求比较高。比如,整个发布的耗时不能太长,毕竟半夜就那点时间。另外,需要停机才能发布,这个对于业务来说是个硬伤,不但失去了灵活性,而且一旦切换期间出现问题,想要回滚的难度也很大。

当然,停机切换的方案,对于需要做的准备工作是最少的,投入的显性成本最低,在一些场景下还是值得选择的。


其实迁移方式主要是两个维度上的考量。

  • 应用程序是否停机

  • 数据的同步是离线进行还是实时进行


根据这两个维度的组合就可以得到四个不同的方案:
  1. 停机+离线

  2. 停机+实时

  3. 不停机+离线

  4. 不停机+实时


我们来一个个聊一下。


01  停机 + 离线

正如前面所说,这个方案是准备工作最少的方案,也俗称一刀切方案。整个过程大概是这样:

1. 对外宣告维护中。
2. 将旧格式的数据批量转换为新格式的数据。
3. 发布新版本的系统。
4. 检查系统功能正常后,宣告维护结束。

核心步骤就两步,但是每一步都是非生即死的操作……,一般适用于小范围内操作,比如非核心的子系统。


02  停机 + 实时

这种方式意味着需要停机的终端系统在更新后的新版本中同时兼容新旧两套服务端系统,通过流量控制进行转发到新 or 旧服务端。新旧两套服务端之间进行数据的实时双向同步。

整个过程是这样的:
  1. 部署新服务端系统。

  2. 建立新老服务端系统之间的双向同步。

  3. 检查同步机制 OK 后,对外宣告维护中。

  4. 发布新版本的终端系统。

  5. 检查系统功能正常后,宣告维护结束。


这种方案很少用到,因为实现终端系统的不停机比服务端数据的实时同步容易得多,一般决定了在服务端层面做实时双向同步,往往也会让终端系统配合着做不停机。


03  不停机 + 离线

这种方案不存在,因为数据既然选择离线迁移,就必然意味着相关的系统必须停机,否则在离线迁移过程中产生的新数据需要反复进行离线迁移,陷入无限循环。


04  不停机 + 实时

这种方式是对业务影响降到最低的方式,但是涉及到的工作也最多。

  1. 部署一套完整的新系统(终端+服务端)。

  2. 检查整套新系统功能正常后,对新访问的用户进行流量切换( APP 的话就是灰度下发升级),将部分流量导到新的终端系统。

  3. 验证新系统的稳定性。如果稳定性出现问题,流量完全切换回旧系统,否则继续提高新系统的流量占比。

  4. 等到流量 100% 切换到新系统之后,完全下线老系统,完成切换。


一般核心的、面向 C 端用户的系统大多会选择这种方式。


我们今天主要对「不停机 + 实时」这个方案的实施细节展开聊一下。

实施中的关键点主要都是围绕数据进行,因为数据同步天然存在延迟,而延迟一旦处理不善不仅仅是系统出现问题,数据的准确性、有效性都会遭到破坏。我们主要的关注点是以下三个:

  1. 数据迁移的方案

  2. 异常数据的识别工具

  3. 异常数据的自动处理机制



/01  数据迁移方案/

数据的迁移主要分为两部分数据。存量数据(已发生的)和增量数据(当前新发生的)。

对新系统来说,只有将老系统的存量数据+增量数据都同步过来,才算真正建立了双向同步通道。

这里延伸出了两个问题:

  • 需要同步的存量数据范围(主要是时间跨度)

  • 临界点的处理方案


迁移的存量数据范围一般要配合相应的功能进行,如果终端系统只对外提供 2 年内的数据,那么只要迁移 2 年内的数据就好了。

这里还可以根据存量数据是否在当前是否继续发生变化,再分为两部分。不发生变化的部分迁移很容易进行,因为不会受到实时数据的干扰,我们可以在实施迁移之前就把数据迁移好。而会发生变化的部分,就是我们需要考虑的「临界点的处理方案」。


针对临界点的处理,也有两种方案。使用哪一种方案取决于系统的数据变更是否依赖同一条数据的上一次变更。有点绕口,简单来说就是系统的数据变动是增量模型还是全量模型。举个例子:

  • 订单管理系统就是全量模型的系统,因为单据的变化依赖于上一次的变化,无法跳过中间的任意一次变化。

  • 库存管理系统就可以设计成增量模型的系统,因为每一次对库存的增加和减少都是独立进行的,不依赖于上一次的变化。


针对全量模型的系统处理数据同步是最难的,因为需要保证数据变更的顺序性。而针对增量模型的系统就会相对简单一些,可以不用保证顺序。


至于进行数据迁移的技术实现,可以选择通过中间件进行,如 DB、MQ等等,也可以选择通过 RPC 调用进行。

但是不管选择什么方式进行数据迁移,有几个原则需要尽可能地遵守。

资源保护原则数据过滤原则数据照搬原则
http://chisc.net/doc/view/3373.html


/02  异常数据的识别工具/

数据同步至新系统的过程中可能会出现数据重复、数据缺失、同步延迟等问题。为了保证迁移过程的可观测性,还需要针对性的开发一个异常数据的识别工具。

这个工具本质上就是做两件事。

  1. 分别采样新旧系统在某些时刻的数据。

  2. 统计出这些时刻新旧系统之间差异情况。(差异数量、差异的同比、环比变化)


如果做得再好一些,可以考虑将数据同步的延迟情况也包含进去。


/03 异常数据的处理/

利用第二步中的工具,我们可以识别出一些异常数据,主要分为三种情况:

  • 数据重复:应对重复数据,主要的思路就是幂等处理。其实这也是应该在制定同步方案的时候就要考虑好的问题。


  • 数据缺失:如果不是 DB 层面的数据同步,数据缺失的情况还是有概率出现的。要么是旧系统发起同步的时候丢了,要么是新系统接收到数据并写入到磁盘的时候出现了异常。解决起来倒也简单,重新同步一下就好了。

  • 数据同步时间差:像订单系统这种全量模型的系统,对于数据同步的延迟容忍度比较低,比如用户来查看自己的订单,发现还是修改之前的信息,就很尴尬。此时,我们可以做一个主动查询旧系统的机制:


  1. 当用户在新系统发起查询某个数据时,我们主动查询一下旧系统。

  2. 如果发现新系统的数据是旧的,则强制同步一次。

  3. 同步完成后,返回给终端展示给用户。(因为是单条数据同步,一般1秒内都能搞定,用户无感)



其实整个实时双向同步方案中,需要考虑的细节还有不少,限于篇幅原因今天就不继续展开了。

比如,可能有必要引入版本号的概念,两边系统共用一个版本号生成器。当发现本地修改时,版本号不是连续的,说明存在两边同时修改的情况,需要做针对性的处理。


思路比具体的方案细节更重要,今天我们就交流一下核心思路。

好了,总结一下。

这篇呢,Z哥和你分享了我最近在做的新老系统切换方案的思路。

切换方案主要从两个维度来考量,停机 or 不停机,数据同步实时 or 离线。常见的方案是「停机+离线」,「不停机+实时」。我们这次主要针对后者展开聊了下。

在实施「不停机+实时」方案的时候,有三个重要的点需要考虑。

  1. 数据迁移的方案

  2. 异常数据的识别工具

  3. 异常数据的自动处理机制


对这三个要点做好考虑,基本上就比较稳了。希望对你有所启发。

不知道你对新老系统的切换,有什么好想法吗?欢迎在留言区分享给大家,相互学习~



推荐阅读:


原创不易,如果你觉得这篇文章还不错,就「点赞」或者「在看」一下吧,鼓励我的创作 :)


也可以分享我的公众号名片给有需要的朋友们。

如果你有关于软件架构、分布式系统、产品、运营的困惑

可以试试点击「阅读原文

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存