zoukankan      html  css  js  c++  java
  • Solr 获取searcher实例分析

    每一个搜索请求都会持有一个searcher的引用,而不是创建一个新的searcher,处理完后会释放掉这个引用

    Solr在初始化化时,通过SolrCore核心类要做很多的初始化工作,包过读取solrconfig.xml配置文件里的内容,代码如下: 

     1 booleanQueryMaxClauseCount(); 
     2 //设置布尔查询最多个数。
     3 initListeners(); 
     4 //读取配置文件的search实例的监听器。
     5 
     6 initDeletionPolicy();
     7 initIndex();
     8 
     9 initWriters();
    10 initQParsers();
    11 
    12 initValueSourceParsers();
    13 this.searchComponents = loadSearchComponents();
    15 // Processors initialized before 
    16 the handlers
    17 updateProcessorChains = loadUpdateProcessorChains();
    19 reqHandlers = new 
    20 RequestHandlers(this);
    21 reqHandlers.initHandlersFromConfig(solrConfig);
    23 highlighter = initHighLighter();
    25 // Handle things that should eventually 
    26 go away
    28 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

  • 相关阅读:
    Security and Cryptography in Python
    Security and Cryptography in Python
    Security and Cryptography in Python
    Security and Cryptography in Python
    Security and Cryptography in Python
    Security and Cryptography in Python
    Security and Cryptography in Python
    微信小程序TodoList
    C语言88案例-找出数列中的最大值和最小值
    C语言88案例-使用指针的指针输出字符串
  • 原文地址:https://www.cnblogs.com/SuperBing/p/2882679.html
Copyright © 2011-2022 走看看