我们使用 Ehcache 作为集群中 Hibernate 的二级缓存。由于我们一台一台地更新服务器以避免停机,在某些时候,集群中的一台服务器可能运行旧版本的代码,而另一台服务器运行更新的版本。
我认为问题出在 Ehcache 上,但我将范围缩小到 Hibernate。 Hibernate 不缓存整个实体,而是缓存字段值的数组。因此,如果您将具有不同模式的实体复制到缓存中,则加载时会发生错误,因为盲目复制数组。
我无法在 Ehcache 级别阻止它。我考虑过在我的实体类上设置 serialVersionUID
,但这不适用于那些较低级别的数组。
我如何向 Hibernate 指示实体版本已更改并且不应加载缓存中的值?
最佳答案
在这种情况下,我认为您无法避免容量暂时下降,因为您所拥有的是一个运行具有不兼容代码库的服务器的系统。
即使您可以评估实体格式的不兼容性及其缓存版本而不是从缓存中加载它,您最终会得到的结果是某些机器会从缓存读取/写入缓存,而有些机器会直接读取到数据库,这将导致数据访问不一致,等等。基本上,这种方法是一堆蠕虫病毒。
有更好的解决方案。这些步骤包括:
- 断开一半集群的网络连接。您可以使用交换机或负载均衡器的管理或任何其他可用的方式。
- 拿下那一半,升级它,把它带上来。
- 重新连接。
- 断开第二个。
- 重复 #2 和 #3。
您在这里得到的是暂时降低容量,同时仍然保持系统可用于在升级时满足客户请求。它可以在非高峰时段很好地工作。随着集群变得越来越可用,您可以通过将新请求路由到集群的升级部分来增强它。还有其他变体,但想法是一样的——分而治之。
唯一重要的是新旧集群不应该互相交谈。您将需要运营方面的帮助,但这当然是可行的。
希望这对您有所帮助。
斯拉瓦伊梅舍夫
关于java - Hibernate - 集群缓存和更新类版本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7172846/