先说明一下,我使用的是solr5.5.3
之前在一篇博客中FastLRUCache中有个重要的方法是warm,当时没有说什么意思,这篇博客就是介绍这个。
warm的意思就是热身,即当一个IndexSearcher因为提交要重新生成一个IndexSearcher的时候,要对新生成的searcher进行warm,我们看一下SolrCore这个类的getSearcher方法,在这个方法里,如果新打开的searcher和之前的searcher不一样(即说明索引发生了变化),就会对新的indexSearcher进行warm,
if (newSearcher != currSearcher) { // warm the new searcher based on the current searcher. // should this go before the other event handlers or after? if (currSearcher != null) { future = searcherExecutor.submit(new Callable() { @Override public Object call() throws Exception { try { newSearcher.warm(currSearcher);//对新的searcher调用warm方法, } catch (Throwable e) { SolrException.log(log, e); if (e instanceof Error) { throw (Error) e; } } return null; } }); } xxxx//如果新的searcher和之前的不一样,还会有其他的操作,这里专门跳出的warm方法
我们到solrIndexSearcher中看看warm方法,
for (int i=0; i<cacheList.length; i++) {//循环所有的cache,然后调用其对应的warm方法, try { this.cacheList[i].warm(this, old.cacheList[i]); } finally { if (debug) log.debug("autowarming result for " + this + "\n\t" + this.cacheList[i]); }
还是到FastLRUCache中去看看吧:
public void warm(SolrIndexSearcher searcher, SolrCache old) { if (regenerator == null) return;//regenerator在初始化一个SolrConfig的时候就会指定,不会是null long warmingStartTime = System.nanoTime(); FastLRUCache other = (FastLRUCache) old; // warm entries if (isAutowarmingOn()) {//这个是根据配置来的,如果我们在<filterCache>(只是举例,其他cache一样)中配置autowarmCount=0就不会进行warm, int sz = autowarm.getWarmCount(other.size());//得到要warm的缓存的大小,因为有的是按照百分比表示的,所以要计算真实大小。 Map items = other.cache.getLatestAccessedItems(sz); Map.Entry[] itemsArr = new Map.Entry[items.size()]; int counter = 0; for (Object mapEntry : items.entrySet()) { itemsArr[counter++] = (Map.Entry) mapEntry; } for (int i = itemsArr.length - 1; i >= 0; i--) { try { boolean continueRegen = regenerator.regenerateItem(searcher,this, old, itemsArr[i].getKey(), itemsArr[i].getValue());//使用regenerator来做warm。 。。。。。。//省略了很多不重要的。 }
还是要到regenerator中去看看这个方法,在org.apache.solr.search.SolrIndexSearcher.initRegenerators(SolrConfig)方法中就会创建多个regenerator,这个方法在创建一个SolrConfig的时候调用,即对在配置文件中出现的cache设置regenerator。他的实现很简单,就是根据原来缓存的key,使用心得searcher来查一遍,放到新的缓存中。
warm因为涉及的代码比较零乱,所以我没有贴代码,不过实现很简单,就是在一个searcher新建立之后将原来的searcher使用的那些缓存重新查一遍保存在新的seracher的cache中。
那么什么时候会重新建立一个searcher呢:1、调用hard commit,2、softCommit,但是索引发生了变化(即添加了doc,但是没有提交的时候)
其实当创建一个新的IndexSearcher的时候不仅仅有warm,还有其他的操作可以配置,下一个博客中介绍。