我目前正在为我们的应用程序提供高可用性功能。

我们的应用程序具有自动更新功能(使用Mongeez),可确保所有数据库/集合/文档的结构采用该应用程序版本的正确格式。

问题是我在解决复制和版本控制问题上遇到了困难。

我将使用以下示例更好地解释问题。

我需要在没有停机的情况下将两台服务器上的Application X更新到Application X2.0,所以我执行以下操作:

  • 停止应用程序X 一个
  • 在服务器上安装2.0版本
  • 启动应用程序X2.0
  • 应用程序X2.0 自动将MongoDB更新为2.0格式
  • 由于我们使用的是MongoDB副本集,因此它将自动在所有MongoDB实例中传播更改
  • 问题!!! ... 应用程序X B 仍在运行版本1.0,但它正在使用数据库/集合/文档结构的2.0版本

  • 我该如何解决这个问题?在上一个“工作流程”中,我在做什么错?

    最佳答案

    让我们假设:

  • F1:格式1.0
  • F2:格式2.0
  • XA:读写F1
  • XB:新应用程序,读写F2(文档2.0)

  • 如果F2与F1兼容,则可以使XA和XB一起运行。
    看来原因不是您所描述的:)

    如果F2与F1不兼容,则有很多工作要做。

    ==============简单方法==================
  • 向您的文档添加version字段(或使用字段来区分F1和F2)
  • 使您的XB与F1&F2兼容:如果读取F1然后写入F1,如果读取F2然后写入F2
  • 将所有应用程序升级到XB(由于此时没有F2,因此不影响XA)
  • 使XB仅写入F2:如果读取F1然后写入F2,则重新部署XB。
  • 将所有F1文档转换为F2

  • ==============常见但复杂的方法===================

    让我们先定义一些概念:
  • C1:F1的集合
  • C2:F2的集合
  • XB:具有用于控制读数的开关的应用程序:从C1或C2。它使用XA的逻辑从C1读取。

  • 脚步:
  • XA运行,在C1中读写F1
  • 将所有数据从C1迁移到C2(从F1升级到F2)
  • 分析并执行操作日志,以确保将C1中的所有新修改都迁移到C2
  • XB从C1读取,写入C1&C2(重要!)
  • 逐步部署XB,XA不受影响,因为C1可用
  • 切换所有XB以从C2读取
  • 删除XB中F1的旧代码

  • 您需要一些程序(脚本)来执行步骤2和步骤3。

    如果您不关心冷数据,则可以跳过步骤2和步骤3,让XB运行一段时间以迁移热数据。

    ==============另一种方法==================
  • 将您的服务器分成几组。例如:G1(XA1,XA2),G2(XA3,XA4)
  • 使用nginx / haproxy平衡您的请求
  • 将所有请求发送到G1(XA1,XA2)
  • 将XB部署到G2,结果:G2(XB3,XB4)
  • 将所有请求发送到G2(XB3,XB4)
  • 将XB部署到G1,结果:G1(XB1,XB2)
  • 将所有请求发送到G1(XB1,XB2)/ G2(XB3,XB4)
  • 将所有F1文档转换为F2

  • 存在风险:
  • 在步骤3 /步骤5中,您的服务器负载可能会超过,因此您需要在非营业时间这样做
  • 如果您在XB中存在错误,则无法回滚。
  • 10-02 23:37