Solr分析

  最近一直在研究Solr的相关源代码,今天开始记录!

           1.SolrCore启动

                首先我们看solrcore的核心构造方法,如下:

public SolrCore(String name, String dataDir, SolrConfig config, IndexSchema schema, CoreDescriptor cd, UpdateHandler updateHandler, IndexDeletionPolicyWrapper delPolicy, SolrCore prev)

    整个solrcore的初始化有这个构造方法完成,主要做了如下几件事情:

     1):initDirectoryFactory()通过solrconfig.xml文件中<directoryFactory/>配置初始化directory工厂,如果没有配置默认则采用NRTCachingDirectoryFactory

       2)获取solr索引根目录,配置在solrConfig.xml文件中

       3) initListeners();初始化后监听器newSearcher。firstSearcher

       4)initIndex():初始化Directory(NRTCachingDirectory)和indexfactory,其中对directory进行缓存

       5)initWriters(),initQParsers();initValueSourceParsers(); initTransformerFactories();后续介绍

       6)通过solrConfig文件初始化相关RequestHandler

       7)getSearcher(false, false, null, true)初始化searcher(下面重点分析这个方法)

   在solrcore的构造方法中有如下一段代码

// cause the executor to stall so firstSearcher events won't fire
      // until after inform() has been called for all components.
      // searchExecutor must be single-threaded for this to work
      searcherExecutor.submit(new Callable<Void>() {
        
        public Void call() throws Exception {
          latch.await();
          return null;
        }
      });

 这个有一段注解,大概意识是说:阻塞线程池,直到所有的组件都初始化完成前不执行firstSearcher这个事件,为什么要这样做了,和我们接下来要分析的getSearcher(false, false, null, true)这个方法有莫大的关系。

    方法定义如下:

          

public RefCounted<SolrIndexSearcher> getSearcher(boolean forceNew, boolean returnSearcher, final Future[] waitSearcher, boolean updateHandlerReopens)
forceNew:true表示强制创建searcher
returnSearcher:true表示返回创建的searcher本质就是searcher引用加1
  

   我们具体代码来分析,首先

      

  if (_searcher!=null && !forceNew) {
        if (returnSearcher) {
          _searcher.incref();
          return _searcher;
        } else {
          return null;
        }
      }
   在solrcore初始化的时候_searcher=null,根据上面提到的参数做相关的处理;
  
if (onDeckSearchers>0 && !forceNew && _searcher==null) {
        try {
          searcherLock.wait();
        } catch (InterruptedException e) {
          log.info(SolrException.toStr(e));
        }
      }

      // check again: see if we can return right now
      if (_searcher!=null && !forceNew) {
        if (returnSearcher) {
          _searcher.incref();
          return _searcher;
        } else {
          return null;
        }
      }
  两次检查,如果发现其他线程在构建search当前线程等待,等待其他线程构建完成直接返回!
searchHolder = openNewSearcher(updateHandlerReopens, false)
  创建一个新的searcher,具体过程就根据SolrIndexSearcher构造函数创建一个searcher 然后包装返回。由于初始化solrcore不存在solr相关的缓存的,所以不存在相关缓存的预热过程,在这个就跳过。后续详细分析。
      if (currSearcher==null && firstSearcherListeners.size() > 0) {
        future = searcherExecutor.submit(
            new Callable() {
              
              public Object call() throws Exception {
                try {
                  for (SolrEventListener listener : firstSearcherListeners) {
                    listener.newSearcher(newSearcher,null);
                  }
                } catch (Throwable e) {
                  SolrException.log(log,null,e);
                }
                return null;
              }
            }
        );
      }

      if (currSearcher!=null && newSearcherListeners.size() > 0) {
        future = searcherExecutor.submit(
            new Callable() {
              
              public Object call() throws Exception {
                try {
                  for (SolrEventListener listener : newSearcherListeners) {
                    listener.newSearcher(newSearcher, currSearcher);
                  }
                } catch (Throwable e) {
                  SolrException.log(log,null,e);
                }
                return null;
              }
            }
        );
      }
  solr相关的事件处理。这个就和上面提到的solrcore构造函数中线程池阻塞有关系.solr构建searcher包含两个事件,在solrconfig文件中可以进行配置,如下    <listener event="newSearcher" class="solr.QuerySenderListener"/>    <listener event="firstSearcher" class="solr.QuerySenderListener">     newSearcher:每次创建新的searcher的时候都执行一次     firstSearcher:solrcore初始化的时候,只执行一次   我们可以通过上面的两个事件做一些数据的初始化,进行相关数据的查询预热。   以上分析比较粗糙,省略了相关细节在后续会慢慢补上,敬请关注!    

猜你喜欢

转载自chenchuan.iteye.com/blog/2037024