具有自动更新和MongoDB副本集的应用程序

时间:2015-04-07 17:20:21

标签: java mongodb updates auto-update high-availability

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

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

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

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

Example

我需要在两台服务器上将Application X更新到Application X2.0而不停机,所以我会执行以下操作:

  1. 停止应用X A
  2. 在服务器 A
  3. 上安装2.0版本
  4. 启动应用程序X2.0 A
  5. 应用程序X2.0 A 自动将MongoDB更新为2.0格式
  6. 由于我们使用的是MongoDB副本集,它会自动传播所有MongoDB实例中的更改
  7. 问题!!! ... 应用程序X B 仍在运行1.0版,但它使用的是2.0版本的数据库/集合/文档结构
  8. 我该如何解决这个问题?我在之前的“工作流程”中做错了什么?

1 个答案:

答案 0 :(得分:0)

我们假设:

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

如果F2与F1兼容,你可以制作XA& XB一起运行。 似乎这个原因并不是你所描述的:)

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

===============简单的方法==================

  1. 在您的文档中添加version字段(或使用字段区分F1和F2)
  2. 让XB与F1& F2兼容:如果它读取F1然后写入F1,如果它读取F2则写入F2
  3. 将所有应用程序升级到XB(XA不受影响,因为此时没有F2)
  4. make XB只写F2:如果它读取F1然后写F2,重新部署XB。
  5. 将所有F1文档转换为F2
  6. ===============普通但复杂的方法==================

    首先定义一些概念:

    • C1:F1的集合
    • C2:F2的收集
    • XB:带有开关控制读数的应用程序:来自C1或C2。它使用XA的逻辑从C1读取。

    步骤:

    1. XA运行,读取&在C1中写道F1
    2. 将所有数据从C1迁移到C2(从F1升级到F2)
    3. 分析并执行oplog以确保C1中的所有新修改都迁移到C2
    4. XB从C1读取,写入C1& C2(重要!)
    5. 逐步部署XB,XA不受影响,因为C1可用
    6. 将所有XB切换为从C2读取
    7. 删除XB中的F1遗留代码
    8. 你需要一些程序(脚本)来做step2&步骤3。

      如果您不关心冷数据,可以跳过step2& step3,让XB运行一段时间来迁移热数据。

      ===============另一种方法==================

      1. 将您的服务器划分为多个组。例如:G1(XA1,XA2),G2(XA3,XA4)
      2. 使用nginx / haproxy平衡您的请求
      3. 将所有请求发送到G1(XA1,XA2)
      4. 将XB部署到G2,结果:G2(XB3,XB4)
      5. 将所有请求发送到G2(XB3,XB4)
      6. 将XB部署到G1,结果:G1(XB1,XB2)
      7. 将所有请求发送到G1(XB1,XB2)/ G2(XB3,XB4)
      8. 将所有F1文档转换为F2
      9. 存在风险:

        1. 在步骤3 /步骤5中,您的服务器负载可能超过,因此您需要在非业务时间执行此操作
        2. 如果您在XB中遇到错误,则无法回滚。