一、背景
Apache Solr 是被廣泛使用的開源搜索引擎,Greenplum DB 的全文檢索組件 Greenplum Text( https://gptext.docs.pivotal.io/330/welcome.html ) 就是基於其構建的。Greenplum Text 簡寫為 GPText,它將 Greenplum 數據庫與 Apache SolrCloud 企業搜索和 MADlib 分析庫進行緊密集成,從而為客戶提供了大規模分析處理和業務決策支持,主要功能包括免費的文本搜索以及對文本分析的支持。
廣義來說,solr 中的 cache 可以分為2大部分:solr 系統的內部 cache 和留給操作系統的文件 cache。對於前者來說,如果設置不當,不但不會提升性能,還將浪費大量內存。
根據長期為客戶調優的經驗,本文作者將對 solr cache 進行簡要介紹並陳述 solr cache 最佳實踐。
二、分類
solr 內部 cache 分為4類:
- QueryResult Cache:緩存 query 對應的 docid 拉鍊,數據結構:query => docid list
- Filter Cache:緩存 filter 對應的 bitmap 索引,數據結構:filter => bitmap (total doc number bit)
- Doc Cache:緩存 doc id 對應的 stored 的 doc 文檔內容,數據結構:doc id => doc content
- Custom Cache,自定義 cache,默認關閉,本文檔中不再介紹
大家需要留意的是這裡給出的數據結構只是樸素實現,而 solr 實際的內部實現比樸素實現更精良(如節省內存),特別是對於 filter cache,詳見solr社區討論( https://lucene.472066.n3.nabble.com/A-question-about-solr-filter-cache-td4455337.html )。
三、配置
在每個索引的 solrconfig.xml 中配置,配置每類索引的最大個數(size),舉例:
<code><filtercache>
<queryresultcache>
<documentcache>/<code>
關於配置,大家需要留意2點內容:
- 前2者還可以設置 maxRamMB 參數(版本要求:solr 6.6中不能配置,7.3.1可以):該類 cache 的使用內存上限,單位是MB。如果配置了它的話,size 和 initialSize 參數將被忽略
- 另外 cache 的生效時間受到 auto/autosoft commit 參數的影響,目前最新 gptext 代碼中配置如下,autocommit 不會導致 cache 失效( 因為設置了 opensearcher 為 false )
<code><autocommit>
<maxdocs>10000/<maxdocs>
<maxtime>60000/<maxtime>
<opensearcher>false/<opensearcher>
/<autocommit>/<code>
autosoftcommit 導致 cache 失效:每 Docs/Time 個週期到了會導致 cache 失效
<code><autosoftcommit>
<maxdocs>100000/<maxdocs>
<maxtime>600000/<maxtime>
/<autosoftcommit>/<code>
四、內存開銷
這裡我們通過一個例子來進行說明,假設某用戶的一個使用場景如下:
- 每個 query/filter 10 Byte
- 平均結果數目:25萬條(每條結果 id 使用一個 8byte 整數代表)
- 總文檔數目:10億(使用一個 bitmap,每個文檔佔 1bit)
- 平均 stored 文檔大小:32 Byte(4個 8byte 字段)
- cache 和 autocommit 參數都是默認值
可以得出每類 cache 的最大大小:
- queryresult cache:(10+250000*8) * 512 = 1GB (最差情況下)
- filter cache:(1000000000/8) * 512 = 60GB (最差情況下)
- doc cache:32 * 512 = 16KB
明顯可見 filter cache 過大,不過以上只是定性分析,便於找出可能的內存瓶頸,實際的內存開銷會更小。
五、監控
如果可以訪問 SOLR UI,可以查看每個 core 上的 cache metrics 統計:
http://localhost:18983/solr/#/demo.public.test_wiki_shard1_replica_n2/plugins?type=cache
如果無法訪問 SOLR UI,直接通過如下 url 查看:
- http://localhost:18983/solr/admin/metrics?group=core&prefix=CACHE.searcher.queryResultCache
- http://localhost:18983/solr/admin/metrics?group=core&prefix=CACHE.searcher.filterCache
- http://localhost:18983/solr/admin/metrics?group=core&prefix=CACHE.searcher.documentCache
例如,通過 SOLR UI 查看 metrics 項目。
重點關注需要 XXX.cumulative_hitratio:它是 solr 節點啟動後積累的命中率,不會受到 cache 清空導致的影響。
六、配置實踐
本文將要給出每類 cache size 的通用設置方法:
首先,持續運行系統一段時間(如一天/一週等),然後蒐集如下系統參數:
- 是否發生了 OOM (out of memory)
- 蒐集每個索引的 cumulative_hitratio(通常只需要關注最大的索引)
如果未發生 OOM,請按照如下流程圖來處理:
如果發生了 OOM,我們就應該關閉或限制某類 cache 的大小:
1.filter cache
- 如前文中實例,一般它是對空間需求最高的 cache 類型,OOM 很可能是由它導致
- 檢查 cumulative_hitratioa。如果高(表明 cache 非常有效),為它設置一個能接受的 maxRamMB 值。如果低,直接關閉(設置size為0)
2. query result cache
- 通常不應該關閉它(往往能發揮作用,如重複搜索一個 query )
- 檢查 cumulative_hitratioa。如果高,為它設置一個能接受的 maxRamMBb 值;如果低,設置一個較小的 maxRamMB 值。
3. document cache
- 通常情況下不是內存瓶頸,因此請首先處理好前2類 cache。
參考:
- https://teaspoon-consulting.com/articles/solr-cache-tuning.html
- https://lucidworks.com/post/scaling-lucene-and-solr/
- https://blog.cloudera.com/apache-solr-memory-tuning-for-production/
- https://blog.cloudera.com/solr-memory-tuning-for-production-part-2/
- https://lucene.apache.org/solr/guide/7_0/performance-statistics-reference.html#statistics-for-caches
- https://blog.csdn.net/john_hongming/article/details/43195849
馬洪旭
Pivotal 資深研發工程師 & Apache HAWQ committer,專注於數據庫領域並熱愛開源技術,目前在 Pivotal 從事 GPText 研發工作。
閱讀更多 Greenplum中文社區 的文章