2014-01-08 65 views
6

我有一个Solr设置。一个主站和两个从站用于复制。我们在索引中有大约70百万份文件。该奴隶有16 GB的RAM。 OS和HD 10GB,Solr 6GB。Solr过滤器缓存(FastLRUCache)占用太多内存并导致内存不足?

但时不时的是,奴隶的内存不足。当我们下载的转储文件之前有人出的内存,我们可以看到类:

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

使用高达5Gb的内存。我们广泛使用过滤器缓存,它有93%的命中率。而这里的solrconfig.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}"/> 

的过滤器高速缓存的XML查询结果的设置相同,但使用LRUCache,它仅使用有关内存的35MB。配置是否有问题需要解决,或者我只需要更多的内存来存储过滤器缓存?

回答

12

一位朋友告诉我过滤器缓存工作的粗略程度后,我们很清楚为什么我们不时发现内存不足的错误。

那么过滤器缓存做什么? 基本上它创建了一些类似于位数组的东西,它告诉哪些文档与过滤器匹配。有些是这样的:

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

1表示命中,0表示命中。所以对于这个例子来说,这意味着过滤器缓存匹配第0个和第3个文档。所以缓存就像一个数组,有着所有文档的长度。假设我有五千万个文档,所以数组长度将是五千万,这意味着一个过滤器缓存将在内存中占用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并不总是创建这个数组,如果过滤器查询的结果很低,它可以创建一些占用较少内存的东西。如果在内存中有2000个高速缓存,这个计算只是说明了过滤器高速缓存的上限大概是多少。在其他更好的情况下,它可能会更低。

因此,一种解决方案是降低solr config中最大过滤器缓存的数量。我们检查了solr统计数据,大部分时间我们只有大约600个过滤器缓存,所以我们可以将过滤器缓存数量减少到最大数量。

另一种选择是当然增加更多的RAM。

+0

将缓存大小减半会使其稳定。由于关于过滤器缓存的解释,我选择了这一个作为答案。但Persimmonium的回答实际上可以做得更好。 – Rowanto

8

一些选项:

  1. 降低高速缓存的大小,看看你是否仍然有不错的命中率
  2. 更换LRU与solr.LFUCache(最Frequenty使用),也许在同一起选择1点仍然会提供一个良好的命中率
  3. 如果查询时,有时你知道FQ将是非常罕见的,不对其进行缓存,通过使用

    FQ = {!缓存= FALSE} inSto CK:真正当然

  4. ,获取更多的内存是另一种选择

  5. 调查,如果DocValues在这里帮助,他们帮助在其他情况下的内存(磨制,整理...),但不知道如果他们使用fq

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