Hibernate Search + Lucene 垃圾收集问题
Hibernate Search + Lucene Garbage Collection Issues
我们有一个 Spring 引导应用程序 运行 Hibernate Search 5.10。7.Final 带有 Lucene 后端,并且每天同一时间 CPU 使用率很高。
线程转储显示消耗 CPU 的线程对应于 JVM 的垃圾收集 activity:
"GC task thread#0 (ParallelGC)" os_prio=0 tid=0x00007fdef801f800 nid=0x173b runnable
"GC task thread#1 (ParallelGC)" os_prio=0 tid=0x00007fdef8021800 nid=0x173c runnable
"GC task thread#2 (ParallelGC)" os_prio=0 tid=0x00007fdef8023800 nid=0x173d runnable
"GC task thread#3 (ParallelGC)" os_prio=0 tid=0x00007fdef8025000 nid=0x173e runnable
堆转储显示 PeriodicRefreshingReaderProvider
的 2 个实例作为最大对象。
还有 3,763 个实例 org.apache.lucene.index.StandardDirectoryReader
。
我对 Hibernate Search 或 Lucene 不够熟悉,无法确定这是否是典型的,我们只需要更大的堆大小或其他问题。
当前最大堆大小为 12GB (-Xmx)。 Apache Lucene 索引仅包含大约 8GB 的磁盘 space.
休眠搜索设置
hibernate.search.default.directory_provider = filesystem
hibernate.search.default.indexBase = /var/lucene/indexes
hibernate.search.default.reader.strategy = async
hibernate.search.default.reader.async_refresh_period_ms = 8000
您显然正在使用 async
refresh strategy,并且引用所有打开的 reader 的地图显然变得非常非常大。
不,那是不正常的。
您提到 CPU 峰值每天都在同一时间发生。您将刷新周期设置为什么? IE。配置属性hibernate.search.[default|<indexname>].reader.async_refresh_period_ms
的值是多少?如果接近 24 小时的值真的很大,那可以解释您的问题。
索引 reader 通常不会保留这么长时间,所以我想它们可能会随着时间的推移变得非常大。如果您遇到这种情况,请尝试将刷新周期缩短到更合理的值,例如1 分钟或 5 分钟:您可能 CPU 更频繁地出现峰值,但峰值要小得多,并且您将使用更少的内存。
或者,某处可能 reader 泄漏。
我想这可能是 Hibernate Search 本身的泄漏,但相关代码已经使用多年,我们还没有看到任何此类泄漏的报告,所以我觉得这很可疑。
您是否在您的应用程序中明确访问了索引 reader?通过getIndexReaderAccessor()?如果是这样,请检查您是否正确关闭了 reader。如果你不这样做,你实际上是在泄漏索引 readers.
我们有一个 Spring 引导应用程序 运行 Hibernate Search 5.10。7.Final 带有 Lucene 后端,并且每天同一时间 CPU 使用率很高。
线程转储显示消耗 CPU 的线程对应于 JVM 的垃圾收集 activity:
"GC task thread#0 (ParallelGC)" os_prio=0 tid=0x00007fdef801f800 nid=0x173b runnable
"GC task thread#1 (ParallelGC)" os_prio=0 tid=0x00007fdef8021800 nid=0x173c runnable
"GC task thread#2 (ParallelGC)" os_prio=0 tid=0x00007fdef8023800 nid=0x173d runnable
"GC task thread#3 (ParallelGC)" os_prio=0 tid=0x00007fdef8025000 nid=0x173e runnable
堆转储显示 PeriodicRefreshingReaderProvider
的 2 个实例作为最大对象。
还有 3,763 个实例 org.apache.lucene.index.StandardDirectoryReader
。
我对 Hibernate Search 或 Lucene 不够熟悉,无法确定这是否是典型的,我们只需要更大的堆大小或其他问题。
当前最大堆大小为 12GB (-Xmx)。 Apache Lucene 索引仅包含大约 8GB 的磁盘 space.
休眠搜索设置
hibernate.search.default.directory_provider = filesystem
hibernate.search.default.indexBase = /var/lucene/indexes
hibernate.search.default.reader.strategy = async
hibernate.search.default.reader.async_refresh_period_ms = 8000
您显然正在使用 async
refresh strategy,并且引用所有打开的 reader 的地图显然变得非常非常大。
不,那是不正常的。
您提到 CPU 峰值每天都在同一时间发生。您将刷新周期设置为什么? IE。配置属性hibernate.search.[default|<indexname>].reader.async_refresh_period_ms
的值是多少?如果接近 24 小时的值真的很大,那可以解释您的问题。
索引 reader 通常不会保留这么长时间,所以我想它们可能会随着时间的推移变得非常大。如果您遇到这种情况,请尝试将刷新周期缩短到更合理的值,例如1 分钟或 5 分钟:您可能 CPU 更频繁地出现峰值,但峰值要小得多,并且您将使用更少的内存。
或者,某处可能 reader 泄漏。
我想这可能是 Hibernate Search 本身的泄漏,但相关代码已经使用多年,我们还没有看到任何此类泄漏的报告,所以我觉得这很可疑。
您是否在您的应用程序中明确访问了索引 reader?通过getIndexReaderAccessor()?如果是这样,请检查您是否正确关闭了 reader。如果你不这样做,你实际上是在泄漏索引 readers.