负载均衡应用程序中的缓存失效

3
我正在开发的应用程序使用简单的HashMap作为缓存,用于存储来自数据库的某些对象。虽然这远非理想,但这些缓存列表中的数据量非常小(少于100),且很少更改。这种解决方案提供了最小的开销。当这些缓存列表中的项目更改时,其值会在HashMap中被替换。
我们即将在生产环境中启动此应用程序。为了提供一个合理可扩展的解决方案,我们提出了一种负载平衡解决方案。负载均衡器在多个Wildfly节点之间切换,每个节点都持有整个应用程序,除了数据库。
问题在于,当缓存项更改时,它只会在一个节点中更新。更改不会应用于其他节点中的缓存。可能的解决方案包括:
- 禁用缓存。不是一个选项。 - 使用Ehcache Server等缓存服务器。这样就会有一个缓存适用于所有节点。然而,由于REST调用过多,问题在于开销太大。 - 每个节点都有一个额外的Web服务。该Web服务将跟踪所有负载平衡节点。当节点中的缓存值更改时,节点会向其他节点发出信号以清除其缓存。 - 带有信号功能的现成解决方案,例如Ehcache。这种解决方案是否存在?
我的问题是:是否有产品提供最后一种解决方案(免费且具有开放许可证,可商业使用)?如果没有,我将实施第三种解决方案。是否有任何风险/错误需要注意?
2个回答

1
我没有使用JGroups或其他信令库来实现。每个节点都有一个REST端点来清除缓存。当节点启动时,它会在DB表中注册自己的IP、域和令牌。当它关闭时,它会删除自己的记录。
当一个对象在一个节点中更新时,该节点会清除其缓存并启动几个线程,使用Unirest向所有其他节点发送一个REST调用(带有其令牌和对象类型),这些节点检查令牌并清除其缓存。当抛出错误时,被调用的节点将从列表中删除。
它应该在安全性和容错性方面得到改善。现在,节点的移除非常悲观。只有在多次失败尝试后才应该删除节点。目前,这个简单的解决方案能够胜任!

长期来看它是否有效 - 如果有的话,你做了哪些改变?截至今日,你发现了任何新的替代方案吗? - Manohar Reddy Poreddy

1

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

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

在更新期间发生缓存未命中时,读取需要等待事务提交。
对于您的用例,典型的选择是集群或分布式缓存,例如:HazelCast、Infinispan、Apache Ignite。然而,在您的用例中,这似乎过于复杂。
一种替代方法是实现自己的机制来发布无效事件到所有节点。但这并不容易,因为您可能希望确保每个节点都收到了消息,但同时也具有容错性,如果一个节点同时关闭,则可以使用适当的库,例如JGroups或各种MQ产品。

你可能是对的,像HazelCast这样的东西可能太重了。我将尝试使用失效事件来实现解决方案,并查看JGroups。谢谢。 - Arthur C
欢迎您。如果您有新发现,请在此处评论/更新。为此问题找到轻量级解决方案确实很有趣。 - cruftex

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接