设为首页 收藏本站
查看: 782|回复: 0

[经验分享] Solr之缓存篇

[复制链接]
发表于 2015-7-19 07:44:43 | 显示全部楼层 |阅读模式
  
原文出自:http://my.oschina.net/u/1026644/blog/123957
  
Solr在Lucene之上开发了很多Cache功能,从目前提供的Cache类型有:
  
(1)filterCache
  
(2)documentCache
  
(3)fieldvalueCache
  
(4)queryresultCache
  
而每种Cache针对具体的查询请求进行对应的Cache。本文将从几个方面来阐述上述几种Cache在Solr的运用,具体如下:
  
(1)Cache的生命周期
  
(2)Cache的使用场景
  
(3)Cache的配置介绍
  
(4)Cache的命中监控
  
1 Cache生命周期
  
所有的Cache的生命周期由SolrIndexSearcher来管理,如果Cache对应的SolrIndexSearcher被重新构建都代表正在运行的Cache对象失效,而SolrIndexSearcher是否重新打开主要有几个方面影响。
  
(1)增量数据更新后提交DirectUpdateHandler2.commit(CommitUpdateCommand cmd),该方法代码如下:

if (cmd.optimize) {
optimizeCommands.incrementAndGet();
} else {
commitCommands.incrementAndGet();
if (cmd.expungeDeletes) expungeDeleteCommands.incrementAndGet();
}
Future[] waitSearcher = null;
if (cmd.waitSearcher) {//是否等待打开SolrIndexSearcher,一般新的Searcher会做一些预备工作,比如预热Cache
waitSearcher = new Future[1];
}
boolean error=true;
iwCommit.lock();
try {
log.info("start "+cmd);
if (cmd.optimize) {//是否优化索引,一般增量数据不优化
openWriter();
writer.optimize(cmd.maxOptimizeSegments);
} else if (cmd.expungeDeletes) {
openWriter();
writer.expungeDeletes();//一般对于标记删除的文档进行物理删除,当然优化也能将标记删除的doc删除,
//但是该方法会比优化快很多
}
closeWriter();//关闭增量打开的Writer对象
callPostCommitCallbacks();
if (cmd.optimize) {//如果有listener的话会执行这部分代码
callPostOptimizeCallbacks();
}
// open a new searcher in the sync block to avoid opening it
// after a deleteByQuery changed the index, or in between deletes
// and adds of another commit being done.
core.getSearcher(true,false,waitSearcher);//该方法是重新打开Searcher的关键方法,
//其中有重要参数来限定是否new open 或者reopen IndexReader.
// reset commit tracking
tracker.didCommit();//提供Mbean的一些状态监控
log.info("end_commit_flush");
error=false;
}
finally {//commlit后将一些监控置0
iwCommit.unlock();
addCommands.set(0);
deleteByIdCommands.set(0);
deleteByQueryCommands.set(0);
numErrors.set(error ? 1 : 0);
}
// if we are supposed to wait for the searcher to be registered, then we should do it
// outside of the synchronized block so that other update operations can proceed.
if (waitSearcher!=null && waitSearcher[0] != null) {
try {
waitSearcher[0].get();//等待Searcher经过一系列操作,例如Cache的预热。
} catch (InterruptedException e) {
SolrException.log(log,e);
} catch (ExecutionException e) {
SolrException.log(log,e);
}
}
}
  
其中最重要的方法

core.getSearcher(true,false,waitSearcher);
  
再展开来看参数含义,
  
参数1 boolean forceNew,是否打开新的searcher对象
  
参数2 boolean returnSearcher,是否返回最新的searcher对象
  
参数3 final Future[] waitSearcher 是否等待searcher的预加工动作,也就是调用该方法的线程将会等待这个searcher对象的预加工动作,如果该searcher对象管理很多的 Cache并设置较大的预热数目,该线程将会等待较长时间才能返回。(预热,也许会很多人不了解预热的含义,我在这里稍微解释下,例如一个Cache已经 缓存了比较多的值,如果因为新的IndexSearcher被重新构建,那么新的Cache又会需要重新累积数据,那么会发现搜索突然会在一段时间性能急 剧下降,要等到Cache重新累计了一定数据,命中率才会慢慢恢复。所以这样的情形其实是不可接受的,那么我们可以做的事情就是将老Cache对应的
key,在重新构建SolrIndexSearcher返回之前将这些已经在老Cache中Key预先从磁盘重新load Value到Cache中,这样暴露出去的SolrIndexSearcher对应的Cache就不是一个内容为空的Cache。而是已经“背地”准备好 内容的Cache)
  
getSearcher()关于Cache有2个最重要的代码段,其一,重新构造新的SolrIndexSearcher:

newestSearcher = getNewestSearcher(false);
String newIndexDir = getNewIndexDir();
File indexDirFile = new File(getIndexDir()).getCanonicalFile();
File newIndexDirFile = new File(newIndexDir).getCanonicalFile();
// reopenReaders在solrconfig.xml配置,如果为false,每次都是重新打开新的IndexReader
if (newestSearcher != null && solrConfig.reopenReaders
&& indexDirFile.equals(newIndexDirFile)) {
IndexReader currentReader = newestSearcher.get().getReader();
IndexReader newReader = currentReader.reopen();//如果索引目录没变则是reopen indexReader
if (newReader == currentReader) {
currentReader.incRef();
}
tmp = new SolrIndexSearcher(this, schema, "main", newReader, true, true);//构建新的SolrIndexSearcher
} else {//根据配置的IndexReaderFactory来返回对应的IndexReader
IndexReader reader = getIndexReaderFactory().newReader(getDirectoryFactory().open(newIndexDir), true);
tmp = new SolrIndexSearcher(this, schema, "main", reader, true, true);//返回构建新的SolrIndexSearcher
}
  
在看看创建SolrIndexSearcher构造函数关于Cache的关键代码:

if (cachingEnabled) {//如果最后的参数为true代表可以进行Cache
ArrayList clist = new ArrayList();
fieldValueCache = solrConfig.fieldValueCacheConfig==null ? null : solrConfig.fieldValueCacheConfig.newInstance();
if (fieldValueCache!=null) clist.add(fieldValueCache);//如果solrconfig配置

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-88093-1-1.html 上篇帖子: PHP添加、更新solr索引 下篇帖子: solr安装-tomcat单机版
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表