一、背景
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点内容:
- 前2者还可以设置maxRamMB参数(版本要求:solr 6.6中不能配置,7.3.1可以):该类cache的使用内存上限,单位是MB。如果配置了它的话,size和initialSize参数将被忽略
- 另外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+2500008) 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