最近,我试图使用Hibernate Search索引,并且正在努力为生产环境找到稳定的解决方案。情况是在Wildfly 10 AS中,我正在使用HibernateOGM PersistenceContext进行索引。这会自动将数据添加到索引(Infinispan文件缓存存储)。

问题是我有一个MDB消耗来自JMS队列的数据,并且我需要调用此函数(onMessage,一个队列条目包含约100万个实体-大请求),以保留约100万个实体并将其发布到另一个AMQP通过无状态EJB排队。

在保留和发布时,我注意到在特定时间段内无法发生主要gc,并且在旧gen充满后,eden空间也变大,并且持久和发布消息的速度大大降低。

我的想法是onMessage函数需要进行事务处理,直到完成,它会将所有数据保留在内存或某些内容(索引或持久数据)中,并且不能仅仅清理旧的gen以便进行回滚。

我提供一些监控图片。您可以轻松地看到,在两个内存空间(旧的gen和eden)都变满并试图变空之后,以将消息发布到另一个队列的速度急剧下降(就像我从一个队列创建一个实体)作为来自jms的请求的列表,我将它们持久化并在for循环中将其发布到Rabbitmq队列)。如果是这种情况,是否可以通过infinispan将索引始终保留在磁盘上?已经在逐出,小块大小等方面尝试了最小值。效果不佳。还尝试更改GC算法,但最终总是处于相同的情况。也许另一个infinispan持久文件存储实现?我现在使用单文件缓存存储,以前使用软索引缓存存储。有什么建议吗?

谢谢

Hibernate Search 5.6.1,Infinispan 8.2.4,Hibernate OGM 5.1,Wildfly 10

VisualGC from visualVM

VisualVM

RabbitMQ

JMS Threads

Hibernate Search Sync Thread

最佳答案

Infinispan(9.2)的最新版本能够“无堆”存储数据,因此简短的回答是可以。但是在选择这样做之前要考虑全局,并不是所有方案都受益于堆外存储,因为这取决于许多因素。

根据定义,Infinispan旨在将最热的数据缓存在内存中,默认情况下是“在堆上”,因为这将只是Java对象时有助于整体性能,因此您可以跳过(反)序列化开销;您需要调整堆大小以适应计划的负载,但它无法自动执行。最简单的策略是,在启用非常大的堆大小时,使用类似的工具在负载下进行观察,然后将其修整为合理的大小,以使其适合您的负载。

因此,在怀疑泄漏或无限制增长之前,请首先验证您是否不是仅对满足其峰值操作要求而言堆太小。如果确实存在实际泄漏,您可能首先要尝试升级,因为这些版本已经很旧了-已经解决了许多问题。

10-07 19:11
查看更多