加载平衡应用程序

时间:2015-12-30 09:39:44

标签: java caching wildfly ehcache

我正在开发的应用程序使用简单的HashMaps作为来自DB的某些对象的缓存。它远非理想,但这些列表的数据量非常小(小于100)并且不会经常变化。此解决方案提供最小的开销当其中一个缓存列表中的项发生更改时,其值将替换为HashMap。

我们已接近此应用程序的制作发布日期。为了提供合理可扩展的解决方案,我们提供了负载平衡解决方案。平衡器在几个Wildfly节点之间切换,每个节点都包含整个应用程序,但DB除外。

现在的问题是,当缓存的项目发生更改时,它只会在其中一个节点中更新。此更改不会应用于其他节点中的缓存。可能的解决方案是:

  • 禁用缓存。不是一种选择。
  • 使用Ehcache Server等缓存服务器。这样,所有节点都会有一个缓存。然而,由于REST调用,问题是开销太大。
  • 每个节点中的其他Web服务。此Web服务将跟踪所有负载平衡节点。当缓存值在节点中发生更改时,该节点将通知其他节点驱逐其缓存。
  • 像Ehcache这样具有信号功能的现成解决方案。这存在吗?

我的问题是:是否有提供最新解决方案的产品(免费且具有开放许可,可在商业上使用)?如果没有,我会实施第三个解决方案。我有什么风险/错误需要注意吗?

2 个答案:

答案 0 :(得分:1)

风险/错误:当然,一个主要问题是数据一致性。从数据库缓存数据时,我通常会确保在更新时使用事务。通常我使用这样的模式:

begin transaction
invalidate cache entries in the transaction
update database
commit transaction

如果在更新期间发生高速缓存未命中,则读取需要等待事务提交。

对于您的用例,典型的选择是群集或分布式缓存,如:HazelCast,Infinispan,Apache Ignite。但是,在你的使用案例中,这种接缝真的很重要。

另一种方法是实现自己的机制,将失效事件发布到所有节点。这仍然不是一项容易的任务,因为您可能希望确保每个节点都收到消息,但如果一个节点同时关闭,也可以容错。所以你可能想要使用一个合适的库,例如JGroups或各种MQ产品。

答案 1 :(得分:0)

我在没有JGroups或其他信令库的情况下实现了它。每个节点都有一个REST端点来驱逐缓存。当节点启动时,它将自己注册到具有IP,域和令牌的DB表中。当它关闭时,它会删除它的记录。

当一个对象在节点中更新时,该节点驱逐其缓存并启动几个线程,使用Unirest向所有其他节点发送REST调用(带有其令牌和对象类型),然后检查令牌并逐出他们的缓存。抛出错误时,将从列表中删除被调用节点。

应该在安全性和容错性方面进行改进。现在删除节点真的很悲观。只有在多次尝试失败后,才应删除该节点。目前,这个简单的解决方案可以完成这项工作!