美文网首页
Solr学习笔记 - 关于timeAllowed

Solr学习笔记 - 关于timeAllowed

作者: 黎明你好 | 来源:发表于2020-07-24 19:39 被阅读0次

    关于timeAllowed

    TimeLimitingCollector

    FilterLeafCollector在collect每个doc的时候判断是否超时

    SolrQueryTimeoutImpl

    如果参数设置了timeAllowed,还会设置一个SolrQueryTimeoutImpl

    SearchHandler:

    long timeAllowed = req.getParams().getLong(CommonParams.TIME_ALLOWED, -1L);
    if (timeAllowed >= 0L) {
        SolrQueryTimeoutImpl.set(timeAllowed);
    }
    

    那么在执行reader在执行加载term的时候就会进行时间检查,超时则会抛出ExitingReaderException异常。

    ExitableFilterAtomicReader:

    /**
     * Throws {@link ExitingReaderException} if {@link QueryTimeout#shouldExit()} returns true,
     * or if {@link Thread#interrupted()} returns true.
     */
    private void checkAndThrow() {
      if (queryTimeout.shouldExit()) {
        throw new ExitingReaderException("The request took too long to iterate over point values. Timeout: "
            + queryTimeout.toString()
            + ", PointValues=" + in
        );
      } else if (Thread.interrupted()) {
        throw new ExitingReaderException("Interrupted while iterating over point values. PointValues=" + in);
      }
    }
    

    主要是在IndexSearch.search方法中加载term的时候。

    public void search(Query query, Collector results) throws IOException {
        query = rewrite(query);
        search(leafContexts, createWeight(query, results.scoreMode(), 1), results);
    }
    
    

    createWeight会调用

    1. IndexSearch.createNormalizedWeight
    2. TermQuery.createWeight
    3. TermContext.build
    4. ExitableTermsEnum 类所有过程会调用checkAndThrow检查超时。

    TermContext.build方法:

     for (final LeafReaderContext ctx : context.leaves()) {
      final Terms terms = ctx.reader().terms(field);
      if (terms != null) {
        final TermsEnum termsEnum = terms.iterator();
        if (termsEnum.seekExact(bytes)) { 
          final TermState termState = termsEnum.termState();
          perReaderTermState.register(termState, ctx.ord, termsEnum.docFreq(), termsEnum.totalTermFreq());
        }
      }
    }
    

    召回阶段

    如果召回阶段超时,抛出 ExitableDirectoryReader.ExitingReaderException 异常,在SearchHandler.handleRequestBody方法里会捕获这个异常,增加partialResults=trued的标识,并返回已经收集的结果。

    rerank阶段

    topCollector.topDocs
    如果rerank阶段超时,由于ReRankCollector.topDocs捕获了所有异常,然后抛出SolrException,导致无结果

    rerank有两处会排除ExitingReaderException异常。

    1. scorer阶段
    scorer = modelWeight.scorer(readerContext);
    

    一般语法为正常的召回,都会在scorer阶段创建weight。同时加载term。

    2. score阶段

    一般是函数计算阶段发生term加载。例如:
    FloatPayloadValueSource.getValues

    public void reset() throws IOException {
        if (terms != null) {
            final TermsEnum termsEnum = terms.iterator();
            if (termsEnum.seekExact(indexedBytes)) {
                docs = termsEnum.postings(null, PostingsEnum.ALL);
            } else {
                docs = null;
            }
        } else {
            docs = null;
        }
        ...
    }
    

    相关文章

      网友评论

          本文标题:Solr学习笔记 - 关于timeAllowed

          本文链接:https://www.haomeiwen.com/subject/wluslktx.html