Solr Filter Cache(FastLRUCache)占用太多内存并导致内存不足?

时间:2014-01-08 15:33:08

标签: java solr lucene out-of-memory

我有一个Solr设置。一个主服务器和两个从服务器用于复制。我们在索引中有大约7000万份文件。从站有16 GB的RAM。 OS和HD为10GB,Solr为6GB。

但是,奴隶不时会记忆犹新。当我们在内存不足之前下载转储文件时,我们可以看到类:

org.apache.solr.util.ConcurrentLRUCache$Stats @ 0x6eac8fb88

正在使用高达5Gb的内存。我们广泛使用过滤缓存,它的命中率为93%。这是solrconfig.xml中过滤器缓存的xml

<property name="filterCache.size" value="2000" />
<property name="filterCache.initialSize" value="1000" />
<property name="filterCache.autowarmCount" value="20" />

<filterCache class="solr.FastLRUCache"
             size="${filterCache.size}"
             initialSize="${filterCache.initialSize}"
             autowarmCount="${filterCache.autowarmCount}"/>

查询结果具有相同的设置,但使用的是LRUCache,它只使用大约35mb的内存。是否有需要修复的配置有问题,或者我只需要更多内存用于过滤器缓存?

2 个答案:

答案 0 :(得分:12)

在一位朋友告诉我过滤缓存的工作原理有多大之后,很明显我们为什么会不时出现内存错误。

那么过滤器缓存有什么作用呢? 基本上它创建类似于数组的东西,它告诉哪些文档与过滤器匹配。有点像:

cache = [1, 0, 0, 1, .. 0]

1表示命中,0表示没有命中。因此,对于该示例,这意味着过滤器缓存匹配第0和第3个文档。因此,缓存有点像一个位数组,具有总文档的长度。因此,假设我有50万个文档,因此数组长度将为50百万,这意味着一个过滤器缓存将占用内存中的50.000.000位。

所以我们指定我们想要2000过滤器缓存,这意味着它将采用的RAM大致是:

50.000.000 * 2000 = 100.000.000.000 bit 

如果将其转换为Gb。它将是:

100.000.000.000 bit / 8 (to byte) / 1000 (to kb) / 1000 (to mb) / 1000 (to gb) = 12,5 Gb

因此,过滤器缓存所需的总RAM大约为12Gb。这意味着如果Solr只有6Gb堆空间,它将无法创建2000个过滤器缓存。

是的,我知道Solr并不总是创建这个数组,如果过滤查询的结果很低,它只能创建一些占用更少内存的东西。这个计算只是粗略地说明过滤器缓存的上限是多少,如果它在ram中有2000个缓存。在其他更好的情况下它可以更低。

因此,一种解决方案是降低solr配置中的最大过滤缓存数量。我们检查了solr统计信息,大多数时候我们只有大约600个过滤器缓存,所以我们可以将过滤器缓存数量减少到最大值。

另一种选择当然是增加更多内存。

答案 1 :(得分:8)

一些选项:

  1. 减少缓存的大小,看看你的命中率是否仍然很高
  2. 用solr.LFUCache替换LRU(使用最少频率),也许与第1点相结合仍会提供良好的命中率
  3. 如果在查询时,有时您知道fq非常罕见,请不要使用

    来缓存它
      

    FQ = {的inStock缓存=假!}:真

  4. 当然,获得更多内存是另一种选择

  5. 调查DocValues是否有帮助,他们在其他场景中帮助记忆(分面,排序......),但不确定他们是否使用fq

  6. 如果您不是最新版本,请升级。