关于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会调用
IndexSearch.createNormalizedWeight
TermQuery.createWeight
TermContext.build
-
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;
}
...
}
网友评论