<!-- Internal cache used by SolrIndexSearcher for filters (DocSets),
unordered sets of *all* documents that match a query.
When a new searcher is opened, its caches may be prepopulated
or "autowarmed" using data from caches in the old searcher.
autowarmCount is the number of items to prepopulate. For LRUCache,
the prepopulated items will be the most recently accessed items.
-->
<filterCache
class="solr.LRUCache"
size="16384"
initialSize="4096"
autowarmCount="4096"/>
对于是否使用filterCache及如何配置filterCache大小,需要根据应用特点、统计、效果、经验等各方面来评估。对于使用fq、facet的应用,对filterCache的调优是很有必要的。 3、queryResultCache
顾名思义,queryResultCache是对查询结果的缓存(SolrIndexSearcher中的cache缓存的都是document id set),这个结果就是针对查询条件的完全有序的结果。下面是它的配置示例:
<!-- queryResultCache caches results of searches - ordered lists of
document ids (DocList) based on a query, a sort, and the range
of documents requested.
-->
<queryResultCache
class="solr.LRUCache"
size="16384"
initialSize="4096"
autowarmCount="1024"/>
public QueryResultKey(Query query, List<Query> filters, Sort sort, int nc_flags) {
this.query = query;
this.sort = sort;
this.filters = filters;
this.nc_flags = nc_flags;
int h = query.hashCode();
if (filters != null) h ^= filters.hashCode();
sfields = (this.sort !=null) ? this.sort.getSort() : defaultSort;
for (SortField sf : sfields) {
// mix the bits so that sortFields are position dependent
// so that a,b won't hash to the same value as b,a
h ^= (h << 8) | (h >>> 25); // reversible hash
if (sf.getField() != null) h += sf.getField().hashCode();
h += sf.getType();
if (sf.getReverse()) h=~h;
if (sf.getLocale()!=null) h+=sf.getLocale().hashCode();
if (sf.getFactory()!=null) h+=sf.getFactory().hashCode();
}
hc = h;
}
因为查询参数是有start和rows的,所以某个QueryResultKey可能命中了cache,但start和rows却不在cache的document id set范围内。当然,document id set是越大命中的概率越大,但这也会很浪费内存,这就需要个参数:queryResultWindowSize来指定document id set的大小。Solr中默认取值为50,可配置,WIKI上的解释很深简单明了:
<!-- An optimization for use with the queryResultCache. When a search
is requested, a superset of the requested number of document ids
are collected. For example, of a search for a particular query
requests matching documents 10 through 19, and queryWindowSize is 50,
then documents 0 through 50 will be collected and cached. Any further
requests in that range can be satisfied via the cache.
-->
<queryResultWindowSize>50</queryResultWindowSize>
相比filterCache来说,queryResultCache内存使用上要更少一些,但它的效果如何就很难说。就索引数据来说,通常我们只是在索引上存储应用主键id,再从数据库等数据源获取其他需要的字段。这使得查询过程变成,首先通过solr得到document id set,再由Solr得到应用id集合,最后从外部数据源得到完成的查询结果。如果对查询结果正确性没有苛刻的要求,可以在Solr之外独立的缓存完整的查询结果(定时作废),这时queryResultCache就不是很有必要,否则可以考虑使用queryResultCache。当然,如果发现在queryResultCache生命周期内,query重合度很低,也不是很有必要开着它。 4、documentCache
又顾名思义,documentCache用来保存<doc_id,document>对的。如果使用documentCache,就尽可能开大些,至少要大过<max_results> * <max_concurrent_queries>,否则因为cache的淘汰,一次请求期间还需要重新获取document一次。也要注意document中存储的字段的多少,避免大量的内存消耗。
下面是documentCache的配置示例:
<!-- documentCache caches Lucene Document objects (the stored fields for each document).
-->
<documentCache
class="solr.LRUCache"
size="16384"
initialSize="16384"/> 5、User/Generic Caches
Solr支持自定义Cache,只需要实现自定义的regenerator即可,下面是配置示例:
<!-- Example of a generic cache. These caches may be accessed by name
through SolrIndexSearcher.getCache(),cacheLookup(), and cacheInsert().
The purpose is to enable easy caching of user/application level data.
The regenerator argument should be specified as an implementation
of solr.search.CacheRegenerator if autowarming is desired.
-->
<!--
<cache name="yourCacheNameHere"
class="solr.LRUCache"
size="4096"
initialSize="2048"
autowarmCount="4096"
regenerator="org.foo.bar.YourRegenerator"/>
-->