滚动更新时如何处理根据以前的应用程序版本存储的数据库数据

问题描述 投票:0回答:2

假设我有一个在 Kubernetes 上运行的系统,使用滚动更新或使用蓝/绿部署的 AWS ECS 或任何其他提供零停机部署的解决方案。这里的关键点是新版本和现有版本可以共存,并且它们使用相同的关系数据库。

我们在数据库中有一个名为

users
的表,其中有一个字段
username
,我们希望在新版本中将其拆分为两个单独的字段:
firstname
lastname
。为此,我们相应地更改服务代码并迁移现有记录。这种情况也适合潜在的回滚。这种情况还应该考虑到潜在的回滚。

在部署过程中,我们首先运行迁移,然后运行滚动更新。据我了解,这可能会导致迁移完成,但以前版本的服务仍在消耗流量的情况。这就是我们以某种方式进行迁移的原因,它支持使用当前版本和新版本。我们添加了新字段,但尚未删除旧字段。

username
字段将在以后的版本中删除。

部署完成后,旧版本将被禁用,只有新版本在运行,分别保存

firstname
lastname
。但这里我们最终遇到一种情况,如果在过渡期间以前的版本存储了一条记录,它将存储在
username
字段中。这些记录不是数据库迁移的主题,因为它们是在 in 启动后创建的。

如何克服这种情况?数据库迁移(仅数据迁移部分)是否应该在部署后启动,或者所描述的过程中可能存在差距?

kubernetes amazon-ecs database-migration blue-green-deployment rolling-updates
2个回答
1
投票

这实际上是一个很好的问题,需要根据升级的方式来设计。

最常见的是通过在升级期间锁定客户端来解决此问题。一种方法是这样的:

  1. 更改客户端使用的数据库用户的密码,或者在客户端支持的情况下使用维护模式(例如,如果是网站,他们可能有一个模式显示“此网站正在临时维护中,请稍后重试)。其他站点只允许站点在升级过程中出现 5xx 错误。
  2. 执行升级。由于客户端无法再访问它,因此您将没有任何合法更新的机会
  3. 等待推出完成
  4. 测试新版本(此处使用新凭据)
  5. 将密码改回原来的密码
  6. 检查您是否仍然可以使用原始凭据进行身份验证
  7. 删除维护模式(如果已启用)
  8. 检查客户端是否能够连接并监控是否有任何错误

0
投票

您提到了蓝/绿或其他零停机部署,所以我认为这是这里的重要部分。不是说可以做到,而是做到零停机。

  1. 您可以控制新应用程序,为什么不让它同时处理已迁移和尚未迁移的数据呢?不要在交换之前迁移数据,而是在交换之后迁移。任何新数据都会正确插入,而旧数据会被迁移,并且应用程序通过在运行时拆分用户名字段来处理丢失的数据。然后在稍后删除该列时删除此版本处理代码。可能有点困难,但目标是零中断,而不是最简单的方法。

  2. 如果您的数据库有插入触发器:将列添加到表后,您可以添加一个插入触发器,该触发器在插入用户名列时触发。触发器本身将执行与迁移相同的拆分逻辑,并在从旧应用程序插入新数据时更新名字和姓氏列。正在更新(而不是插入)的迁移不会触发触发器,并且新的应用程序代码将不包含用户名列,因此它也不会触发触发器。这将允许您在旧应用程序运行时运行迁移,然后切换到新应用程序,而无需第一种方法中的附加应用程序代码。当您删除当前未使用的用户名列时,只需删除当前未使用的触发器即可。

我认为重要的是,确保您的更新不会使用适当的批处理技术进行过多的独占锁。阻塞读取操作会迅速陷入一个巨大的阻塞进程队列,从而导致数据库服务器瘫痪。使用保存时间非常短的小型索引更新批次。这可能会使迁移花费更长的时间,但谁在乎网站是否运行良好,并且任何生成的读取块仅保留几毫秒,而用户不会注意到。

© www.soinside.com 2019 - 2024. All rights reserved.