2015-12-30 81 views
2

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

我们即将推出此应用程序的生产日期。为了提供合理的可扩展解决方案,我们提供了一个负载平衡解决方案。平衡器在几个Wildfly节点之间切换,每个节点都保存整个应用程序,但数据库除外。

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

  • 禁用缓存。没有选择。
  • 使用像Ehcache Server这样的缓存服务器。通过这种方式,所有节点都会有一个缓存。但是,由于REST调用,问题会导致太多的开销。
  • 每个节点中的附加Web服务。该Web服务将跟踪所有负载平衡节点。当某个节点中的缓存值发生变化时,该节点将向其他节点发出信号以驱逐其缓存。
  • 像Ehcache这样的现成解决方案,具有信号功能。这是否存在?

我的问题是:是否有产品提供最后的解决方案(免费和开放许可证,商业可用)?如果不是,我会实施第三种解决方案。有什么风险/错误我不得不注意?

回答

1

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

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

在更新过程中高速缓存未命中的情况下发生的读取需要等到事务提交。

对于您的用例,典型的选择是集群或分布式缓存,如:HazelCast,Infinispan,Apache Ignite。但是,不管怎样,这在您的用例中确实会非常沉重。

另一种方法是实现一个自己的机制来向所有节点发布无效事件。不过这不是一件容易的事情,因为您可能想确保每个节点都收到该消息,但是如果一个节点同时发生故障,它也是容错的。所以你可能想使用一个合适的库,例如JGroups或各种MQ产品。

+0

你很可能是正确的,像HazelCast会太重。我会尝试使用失效事件来实施解决方案,并查看JGroups。谢谢。 –

+0

不客气。 PLS。如果您有新的发现,请点击此处更新/评论。找到解决这个问题的轻量级解决方案确实很有趣。 – cruftex

0

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

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

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