Caching 如何配置Lucene(SOLR)内部缓存-内存问题/泄漏?

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

我正在使用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. */
  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)有关。谢谢