2014-01-08 100 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. 如果你不是最新版本,升級。