Infinispan Cluster - 滚动升级 - 数据模型的变化

时间:2014-08-07 09:16:55

标签: migration upgrade infinispan

我有一个在嵌入式+复制模式下使用Infinispan的集群。群集大小只是2个系统,它们在主动 - 待机模式下工作。

我需要支持我的应用程序的滚动升级。我还必须不要丢失过程中的任何缓存数据。

为了说明, 在我的应用程序版本v1中考虑一个简单的类User:

public class User {
    private String role;
    private String firstName;
}

在版本v2中,我向User类添加了一个属性:

public class User {
    private String role;
    private String firstName;
    private String lastName;
}

我的应用程序升级如下:

  1. 使用节点n1(活动)和n2(备用)创建的群集,我的应用程序版本v1在这两个节点上运行。创建了10个用户对象,这些用户对象构成了我的密钥或infinispan缓存c1值的一部分。
  2. 在主动节点n1上启动升级。
  3. n1完成预检查并在备用节点n2上调用升级。
  4. n2断开自身与群集的连接,使用新版本v2重新启动。
  5. n2连接回群集,这又会触发节点n1的升级。
  6. n1完成升级,提供版本v2并加入群集。
  7. 升级完成。
  8. 在步骤5,当n2连接回群集时,节点n1上版本v1中的User类与节点n2上版本v2中的User类不同。

    在我与节点n2同步之前,我也不能升级节点n1,因为这会导致数据丢失,我也不能指望节点n2获取所有数据并更新其缓存,因为c1键中的模型更改/值。

    那么我该如何处理这种情况呢。 User类也可能会发生更改,例如删除/更改属性的数据类型或删除类本身。

    是否有任何最佳实践或众所周知的方法来处理使用infinispan缓存的滚动升级?

    我还需要在升级活动期间处理节点n1上的缓存更新,并确保节点n2的缓存(已在版本v2中)获得这些更新。

    注意:我在嵌入模式下使用5.3.0的Infinispan。

2 个答案:

答案 0 :(得分:4)

Infinispan具有用于升级Infinispan版本的滚动升级功能,其中包括新集群生成和应用程序切换到新集群。然后,当请求一些数据时,新集群从旧集群中检索这些数据,但所有写入仅转到新集群 - 最终所有数据都移动到新集群(我认为还有一些选项可以急切地推送它们)

但是,这不适用于数据升级 - 我没有找到任何方法来为升级注入代码。建议的做法是让User类具有Externalizable,并在加入节点中切换到新的marshaller - marshaller可以处理这两种格式。但是,我不确定这是否适用于缓存中已不支持外部化的数据。

另一个选项非常复杂:生成新的集群(单个节点),并在您的应用程序中使用包装器进行缓存操作,这将在以下情况下执行:

  • 读取:从新集群中获取值,如果为空,则从旧集群获取该值,转换并写入新集群,并从旧集群中删除
  • 写:将值写入新群集并从旧群集中删除
  • 删除:从两个群集中删除

然后,我将生成一个线程,该线程将从旧集群读取数据并将putIfAbsent读取到新集群中。这有一点竞争:你可以在刚删除数据时将数据放到新集群中。解决此问题需要您在新群集中保留一些逻辑删除,直到迁移所有数据。正如我所说,这将是非常复杂的:)

答案 1 :(得分:0)

我遇到了类似的情况。这就是我解决它的方法:

  1. 在升级之前将当前缓存的内容写入某种持久性

  2. 使用不同的群集设置创建新的缓存,以便它不会与现有缓存一起复制。

  3. 此新缓存将用于已升级的节点。
  4. 升级后的节点一出现,就会读取持久性并根据新的数据模型更新缓存。
  5. 两个节点升级后,旧缓存最终会消失。