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

一、背景

Apache Solr是被广泛使用的开源搜索引擎,Greenplum DB的全文检索组件Greenplum Text就是基于其构建的: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社区讨论

三、配置

在每个索引的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_hitratioa. 如果高(表明cache非常有效),为它设置一个能接受的maxRamMB值b. 如果低,直接关闭(设置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

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研发工作。

关注微信公众号

VMware 中国研发中心