solr索引分发处理以及搜索的更新与替换

今天对solr的分发机制研究一翻。。心中有几个疑问,IndexSearcher的切换是否导致服务停止?答案是不会。。

 

查看了solr实现这一切换的思路:

 

  首先处理solr分发的类org.apache.solr.handler.ReplicationHandler,其中有一段

 

 if (command.equalsIgnoreCase(CMD_FETCH_INDEX)) {
      String masterUrl = solrParams.get(MASTER_URL);
      if (!isSlave && masterUrl == null) {
        rsp.add(STATUS,ERR_STATUS);
        rsp.add("message","No slave configured or no 'masterUrl' Specified");
        return;
      }
      final SolrParams paramsCopy = new ModifiableSolrParams(solrParams);
      new Thread() {
        public void run() {
          doFetch(paramsCopy);
        }
      }.start();
      rsp.add(STATUS, OK_STATUS);
    }

 

 

可以看出是启动了一个线程来处理分发请求,主要是从主机那拷贝索引来。

  if (!modifiedConfFiles.isEmpty()) {
          downloadConfFiles(confFilesToDownload, latestVersion);
          if (isFullCopyNeeded) {
            modifyIndexProps(tmpIndexDir.getName());
          } else {
            successfulInstall = copyIndexFiles(tmpIndexDir, indexDir);
          }
          if (successfulInstall) {
            LOG.info("Configuration files are modified, core will be reloaded");
            logReplicationTimeAndConfFiles(modifiedConfFiles, successfulInstall);//write to a file time of replication and conf files.
            reloadCore();
          }
        } else {
          terminateAndWaitFsyncService();
          if (isFullCopyNeeded) {
            successfulInstall = modifyIndexProps(tmpIndexDir.getName());
            deleteTmpIdxDir =  false;
          } else {
            successfulInstall = copyIndexFiles(tmpIndexDir, indexDir);
          }
          if (successfulInstall) {
            logReplicationTimeAndConfFiles(modifiedConfFiles, successfulInstall);
            doCommit();
          }
        }

 

拷贝完主机索引后,此时子机接收到新的索引,此时如果solrconfig.xml或者schema.xml配置文件发生改变,会启动一个新线程重新加载新的SolrCore对象

 

   private void reloadCore() {
    new Thread() {
      public void run() {
        try {
          solrCore.getCoreDescriptor().getCoreContainer().reload(solrCore.getName());
        } catch (Exception e) {
          LOG.error("Could not restart core ", e);
        }
      }
    }.start();
  }

重新加载schema.xml与solrconfig.xml里的实例与组件。

 CoreContainer存放多个solrCore,由

protected final Map<String, SolrCore> cores = new LinkedHashMap<String, SolrCore>();

一个链表hashMap来存储,根据不同的名称映射其对象的引用空间。

  synchronized (cores) {
      old = cores.put(name, core);
      core.setName(name);
    }

加载完solrcore后替换旧的solrcore引用地址。。

 

如果配置文件没有发生改变,则重用原来的solrcore,重新打开writer与indexSearcher,其中切换IndexSearcher的部分代码如下。

 

  private void registerSearcher(RefCounted<SolrIndexSearcher> newSearcherHolder) throws IOException {
    synchronized (searcherLock) {
      try {
        if (_searcher != null) {
          _searcher.decref();   // dec refcount for this._searcher
          _searcher=null;
        }

        _searcher = newSearcherHolder;
        SolrIndexSearcher newSearcher = newSearcherHolder.get();

        newSearcher.register(); // register subitems (caches)
        log.info(logid+"Registered new searcher " + newSearcher);

      } catch (Throwable e) {
        log(e);
      } finally {
        // wake up anyone waiting for a searcher
        // even in the face of errors.
        onDeckSearchers--;
        searcherLock.notifyAll();
      }
    }
  }

 

在切换过程中有启动多条线程来进行拷贝旧的IndexSearcher中的缓存与处理事件。

——————————————————————————————————

  newSearcher.warm(currSearcher);

————————————————————————

 for (SolrEventListener listener : firstSearcherListeners) {
                        listener.newSearcher(newSearcher,null);
                      }

 ——————————————————————————————

 

 for (SolrEventListener listener : newSearcherListeners) {
                        listener.newSearcher(newSearcher, currSearcher);
                      }

 

————————————————————————————————————

 

 

还有个疑问,在替换原来的索引文件时,会进行删除的动作,这样旧的索引文件就会被删除掉,那么,旧的IndexSearcher在处理请求时,读取旧索引文件,这个会出现异常吗?

 

答案是不会的,因为从操作系统的角度来讲,一旦一个文件被打开一个inputstream也即打开了一个文件描述符,在内核中,此文件会保持reference count,只要reader 还没有关闭,文件描述符还在,文件是不会被删除的,仅仅reference count 减一。

 

本文链接:http://blog.csdn.net/duck_genuine/archive/2011/04/26/6363844.aspx

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值