Caching 如何配置Lucene(SOLR)内部缓存-内存问题/泄漏?
我正在使用Solr4.4.0-我发现(可能)与内部缓存机制相关的问题。 JVM:-Xmx=15g,但12g从来都不是免费的。 我创建了堆转储并使用MemoryAnyzer对其进行分析-我发现2 x 6Gb用作缓存数据。 第二次我对-Xmx12g做了同样的操作,我发现了1 x 3.5Gb 它总是同一个缓存。 我签入源代码后发现:Caching 如何配置Lucene(SOLR)内部缓存-内存问题/泄漏?,caching,memory,solr,lucene,out-of-memory,Caching,Memory,Solr,Lucene,Out Of Memory,我正在使用Solr4.4.0-我发现(可能)与内部缓存机制相关的问题。 JVM:-Xmx=15g,但12g从来都不是免费的。 我创建了堆转储并使用MemoryAnyzer对其进行分析-我发现2 x 6Gb用作缓存数据。 第二次我对-Xmx12g做了同样的操作,我发现了1 x 3.5Gb 它总是同一个缓存。 我签入源代码后发现: /** Expert: The cache used internally by sorting and range query classes. */ publ
/** Expert: The cache used internally by sorting and range query classes. */
public static FieldCache DEFAULT = new FieldCacheImpl();
看
这是一个非常坏的消息,因为它是公共静态字段,在源代码中大约有160处使用了它
记忆分析者说:
加载的“org.apache.lucene.search.FieldCacheImpl”的一个实例
“org.apache.catalina.loader.WebappClassLoader@0x58c3a9848”占据
4103248240(80.37%)字节。记忆是一次积累
“”加载的“java.util.HashMap$Entry[]”实例
关键词java.util.HashMap$Entry[]
org.apache.catalina.loader.WebappClassLoader@0x58c3a9848
org.apache.lucene.search.FieldCacheImpl
我不知道如何管理这种缓存-有什么建议吗
最后我退出了内存错误+12Gb内存被阻塞。如果您使用FieldCacheRangeFilter,您可能想尝试不使用字段缓存的范围筛选器。如果排序是一个问题,您可以尝试使用较少的排序字段,或者使用较少内存的数据类型字段 当读卡器被垃圾收集时,每个读卡器/原子读卡器的字段缓存被丢弃。因此,读取器的重新初始化应该清除缓存,这也意味着第一次使用缓存的操作将慢得多
事实是:基于FieldCache的范围筛选和排序依赖于缓存。当你真的需要这些东西时,你是无法走动的。您只能调整您的使用以最小化内存消耗。我实施了一种解决方法: 我创建了这样的类:
public class InternalApplicationCacheManager implements InternalApplicationCacheManagerMBean {
public synchronized int getInternalCacheSize() {
return FieldCache.DEFAULT.getCacheEntries().length;
}
public synchronized void purgeInternalCaches() {
FieldCache.DEFAULT.purgeAllCaches();
}
}
并通过org.apache.lucene.search.FieldCacheImpl在JMX中注册
...
private synchronized void init() {
...
initBeans();
}
private void initBeans() {
try {
InternalApplicationCacheManager cacheManagerMBean = new InternalApplicationCacheManager();
MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
ObjectName name = new ObjectName("org.apache.lucene.search.jmx:type=InternalApplicationCacheManager");
mbs.registerMBean(cacheManagerMBean, name);
} catch (InstanceAlreadyExistsException e) {
...
}
}
...
此解决方案可使内部缓存失效,从而部分解决此问题。
不幸的是,还有一些地方(主要是缓存)存储了一些数据,但删除速度不如我预期的快。如何最大限度地减少内存消耗?即使我卸载指定的集合,在查询执行期间加载到缓存中的数据也不会从SOLR中释放。不使用fieldcacherangefilter,不使用排序或减少排序字段的数量,更改排序字段类型,例如,如果可能的话,从long到int。好的,但这听起来似乎不是这个问题的解决方案-一切正常,但SOLR没有释放缓存数据(即使我卸载了收集)。我会更深入地调查。你说的“收藏”是什么意思?只要读卡器存在,lucene就永远不会释放缓存。这就是为什么我说,只有在关闭和删除读卡器时才能释放缓存。不知道solr的内部结构。我抓到你了。这意味着这个问题可能与SOLR(而不是Lucene)有关。谢谢