我有一个在嵌入式+复制模式下使用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;
}
我的应用程序升级如下:
在步骤5,当n2连接回群集时,节点n1上版本v1中的User类与节点n2上版本v2中的User类不同。
在我与节点n2同步之前,我也不能升级节点n1,因为这会导致数据丢失,我也不能指望节点n2获取所有数据并更新其缓存,因为c1键中的模型更改/值。
那么我该如何处理这种情况呢。 User类也可能会发生更改,例如删除/更改属性的数据类型或删除类本身。
是否有任何最佳实践或众所周知的方法来处理使用infinispan缓存的滚动升级?
我还需要在升级活动期间处理节点n1上的缓存更新,并确保节点n2的缓存(已在版本v2中)获得这些更新。
注意:我在嵌入模式下使用5.3.0的Infinispan。
答案 0 :(得分:4)
Infinispan具有用于升级Infinispan版本的滚动升级功能,其中包括新集群生成和应用程序切换到新集群。然后,当请求一些数据时,新集群从旧集群中检索这些数据,但所有写入仅转到新集群 - 最终所有数据都移动到新集群(我认为还有一些选项可以急切地推送它们)
但是,这不适用于数据升级 - 我没有找到任何方法来为升级注入代码。建议的做法是让User类具有Externalizable,并在加入节点中切换到新的marshaller - marshaller可以处理这两种格式。但是,我不确定这是否适用于缓存中已不支持外部化的数据。
另一个选项非常复杂:生成新的集群(单个节点),并在您的应用程序中使用包装器进行缓存操作,这将在以下情况下执行:
然后,我将生成一个线程,该线程将从旧集群读取数据并将putIfAbsent读取到新集群中。这有一点竞争:你可以在刚删除数据时将数据放到新集群中。解决此问题需要您在新群集中保留一些逻辑删除,直到迁移所有数据。正如我所说,这将是非常复杂的:)
答案 1 :(得分:0)
我遇到了类似的情况。这就是我解决它的方法:
在升级之前将当前缓存的内容写入某种持久性
使用不同的群集设置创建新的缓存,以便它不会与现有缓存一起复制。