vlambda博客
学习文章列表

Solr Cache最佳实践帮你轻松调优


背景

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),举例:
<filterCache class="solr.FastLRUCache" size="512" initialSize="512" autowarmCount="0" /><queryResultCache class="solr.LRUCache" size="512" initialSize="512" autowarmCount="0" /><documentCache class="solr.LRUCache" size="512" initialSize="512" autowarmCount="0" />
(左划查看代码)

关于配置,大家需要留意2点内容:

  1. 前2者还可以设置maxRamMB参数(版本要求:solr 6.6中不能配置,7.3.1可以):该类cache的使用内存上限,单位是MB。如果配置了它的话,size和initialSize参数将被忽略
  2. 另外cache的生效时间受到auto/autosoft commit参数的影响,目前最新gptext代码中配置如下:

autocommit不会导致cache失效(因为设置了opensearcher为false)

<autoCommit><maxDocs>10000</maxDocs><maxTime>60000</maxTime><openSearcher>false</openSearcher></autoCommit>


autosoftcommit导致cache失效:每Docs/Time个周期到了会导致cache失效


<autoSoftCommit><maxDocs>100000</maxDocs><maxTime>600000</maxTime></autoSoftCommit>



内存开销

这里我们通过一个例子来进行说明,假设某用户的一个使用场景如下:

  • 每个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的通用设置方法:


首先,持续运行系统一段时间(如一天/一周等),然后搜集如下系统参数:


1. 是否发生了OOM (out of memory) 
2. 搜集每个索引的cumulative_hitratio(通常只需要关注最大的索引) 


如果未发生OOM,请按照如下流程图来处理:



如果发生了OOM,我们就应该关闭或限制某类cache的大小:

1.filter cache


  • 如前文中实例,一般它是对空间需求最高的cache类型,OOM很可能是由它导致

  • 检查cumulative_hitratio

    a.  如果高(表明cache非常有效),为它设置一个能接受的maxRamMB值
    b.  如果低,直接关闭(设置size为0)


2. query result cache

  • 通常不应该关闭它(往往能发挥作用,如重复搜索一个query)值

  • 检查cumulative_hitratio

    a.  如果高,为它设置一个能接受的maxRamMB

    b. 如果低,设置一个较小的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研发工作。