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

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

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

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

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

     

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

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

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

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

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

所以我们指定我们想要2000filter缓存,这意味着它将采取的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 

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

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

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

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

一些选择:

  1. 减小缓存的大小,看看你是否仍然有一个很好的命中率
  2. 用solr.LFUCache替换LRU(Least Frequenty Used),也许与第1点相结合仍然可以提供良好的命中率
  3. 如果在查询时,有时你会知道fq非常罕见,不要通过使用来缓存它

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

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

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

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