CONAN ZONE

你越挣扎我就越兴奋

BlogJava 首页 新随笔 联系 聚合 管理
  0 Posts :: 282 Stories :: 0 Comments :: 0 Trackbacks
每一个搜索请求都会持有一个searcher的引用,而不是创建一个新的searcher,处理完后会释放掉这个引用

Solr在初始化化时,通过SolrCore核心类要做很多的初始化工作,包过读取solrconfig.xml配置文件里的内容,代码如下:
  
 booleanQueryMaxClauseCount(); //设置布尔查询最多个数。
    initListeners();  //读取配置文件的search实例的监听器。
    initDeletionPolicy();
    initIndex();
    initWriters();
    initQParsers();
    initValueSourceParsers();
    this.searchComponents = loadSearchComponents();
    // Processors initialized before the handlers
    updateProcessorChains = loadUpdateProcessorChains();
    reqHandlers = new RequestHandlers(this);
    reqHandlers.initHandlersFromConfig( solrConfig );
    highlighter = initHighLighter();
    // Handle things that should eventually go away
    initDeprecatedSupport();

loadSearchComponents方法就是初始化indexSearch实例。详细说明如下:
getSearcher – (forceNew, returnSearcher, waitSearcher-Futures)
关注solr全局三个点调用getSearcher函数 : solrCore初始化时(false, false, null),QueryComponent处理查询
请求时(false, true, null),UpdateHandler在处理commit请求时(true, false, new Future[1])
---------
1.solrCore初始化时
根据solrconfig配置的IndexReaderFactory&DirectoryFactory获取索引的IndexReader,再使用这个reader
封装一个SolrIndexReader,再使用这个SolrIndexReader封装一个RefCounted(searcher的引用计数器,当搜索
组件获取一个组件后引用++,用完后调用close引用--,当引用数为0时将这个引用从core管理的一个当前被使用的
searcher的链表移除,同时调用searcher.close回收资源),将这个引用添加到core管理的一个当前被使用的searcher
的链表里如果firstSearcherListeners不为空则回调这些监听器,这个回调是交给core的一个newSingleThreadExecutor去
做的,再往这个线程池里添加一个任务:将这个RefCounted设置为core当前最新的searcher的引用计数器
最后返回null,因为returnSearcher=false
在solrCore初始化时这样做的主要目的是在初始化时就加载好IndexSearcher,搜索请求来了之后能立即返回,
而不必等待加载IndexSearcher
---------
2.QueryComponent处理查询请求时
由于core当前最新的searcher的引用计数器不为null且这个获取IndexSearcher的请求不是强制要求获取最新的,且
returnSearcher=true故直接返回core当前最新的searcher的引用计数器,且这个引用计数器做++
这里面还有段当前searcher的引用计数器为null的逻辑,但是没有发现有什么情况会导致这种情况发生故不累述了
---------
3.UpdateHandler在处理commit请求时
首先到core管理的一个当前被使用的searcher的链表里获取目前最新的searcher;同时会加载索引目录下的
index.properties文件(如果存在的话),拿到KEY=’index’的值,其指明目前索引的存放地方;如果获取的目录和当前
最新的searcher使用的目录一致且solrConfig.reopenReaders为true则获取通过searher.reader.reopen获取
最新的reader -> 封装成searcher,否则直接IndexReader.open获取reader。
获取到searcher后的一段逻辑[RefCount封装,添加到searchers链表]和core初始化时是一样的,接下来的逻辑是
如果solrConfig.useColdSearcher为TRUE其当前searcher的引用为null-导致来自QueryComponent的请求阻塞
[现在还没发现什么情况会导致searcher的引用为null]
立即将这个新的searcher的引用设置为core当前最新的searcher的引用计数器,这样来自QueryComponent的请求
拿到这个引用后返回,当时这时这个新建的searcher是没有经过其前一个searcher的cache热身的,同时这样会导致这个
新建的searcher不会进行热身活动
如果solrConfig.useColdSearcher为FALSE则会往线程池里添加一个热身的任务
如果newSearcherListeners不为空则回调这些监听器,也是给线程池的任务
最后如果先前没有做将新的searcher的引用设置为core当前最新的searcher的引用计数器的行为的话,则往线程池添加
一个任务 – 将新的searcher的引用设置为core当前最新的searcher的引用计数器
最后返回null,因为returnSearcher=false

from:http://blog.sina.com.cn/s/blog_56fd58ab0100v3tp.html
posted on 2012-06-13 14:17 CONAN 阅读(1483) 评论(0)  编辑  收藏 所属分类: Solr