1.AbstractRunnable
run:38, AbstractRunnable (org.elasticsearch.common.util.concurrent)
doRun:638, ThreadContext$ContextPreservingAbstractRunnable (org.elasticsearch.common.util.concurrent)
2.SearchService
doRun:1000, SearchService$3 (org.elasticsearch.search)
onResponse:271, SearchService$2 (org.elasticsearch.search)
onResponse:278, SearchService$2 (org.elasticsearch.search)
3.SearchTransportService
onResponse:364, SearchTransportService$6$1 (org.elasticsearch.action.search)
onResponse:368, SearchTransportService$6$1 (org.elasticsearch.action.search)
4.RequestHandlerRegistry
sendResponse:108, RequestHandlerRegistry$TransportChannelWrapper (org.elasticsearch.transport)
5.DelegatingTransportChannel
sendResponse:69, DelegatingTransportChannel (org.elasticsearch.transport)
6.TransportService
sendResponse:1135, TransportService
D
i
r
e
c
t
R
e
s
p
o
n
s
e
C
h
a
n
n
e
l
(
o
r
g
.
e
l
a
s
t
i
c
s
e
a
r
c
h
.
t
r
a
n
s
p
o
r
t
)
s
e
n
d
R
e
s
p
o
n
s
e
:
1159
,
T
r
a
n
s
p
o
r
t
S
e
r
v
i
c
e
DirectResponseChannel (org.elasticsearch.transport) sendResponse:1159, TransportService
DirectResponseChannel(org.elasticsearch.transport)sendResponse:1159,TransportServiceDirectResponseChannel (org.elasticsearch.transport)
processResponse:1176, TransportService
D
i
r
e
c
t
R
e
s
p
o
n
s
e
C
h
a
n
n
e
l
(
o
r
g
.
e
l
a
s
t
i
c
s
e
a
r
c
h
.
t
r
a
n
s
p
o
r
t
)
h
a
n
d
l
e
R
e
s
p
o
n
s
e
:
1082
,
T
r
a
n
s
p
o
r
t
S
e
r
v
i
c
e
DirectResponseChannel (org.elasticsearch.transport) handleResponse:1082, TransportService
DirectResponseChannel(org.elasticsearch.transport)handleResponse:1082,TransportServiceContextRestoreResponseHandler (org.elasticsearch.transport)
7.ActionListenerResponseHandler
handleResponse:46, ActionListenerResponseHandler (org.elasticsearch.action)
8.SearchExecutionStatsCollector
onResponse:36, SearchExecutionStatsCollector (org.elasticsearch.action.search)
onResponse:68, SearchExecutionStatsCollector (org.elasticsearch.action.search)
9.SearchActionListener
onResponse:32, SearchActionListener (org.elasticsearch.action.search)
onResponse:51, SearchActionListener (org.elasticsearch.action.search)
10.InitialSearchPhase
innerOnResponse:223, InitialSearchPhase$2 (org.elasticsearch.action.search)
access$000:50, InitialSearchPhase (org.elasticsearch.action.search)
maybeFork:176, InitialSearchPhase (org.elasticsearch.action.search)
private void performPhaseOnShard(. ..) {
executePhaseOnShard(.. .) {
//收到执行成功的回复
public void inne rOnResponse (FirstResult result) {
maybeFork (thread, () -> onShardResult (result,shardIt) );
}
//收到执行失败的回复
public void onFailure (Exception t) {
maybeFork(thread, () -> onShardFailure (shardIndex, shard, shard. currentNodeId(),shardIt, t));
}
});
}
run:-1, 86025122 (org.elasticsearch.action.search.InitialSearchPhase
2
2
2$Lambda
1798
)
c
o
n
s
u
m
e
R
e
s
u
l
t
:
385
,
I
n
i
t
i
a
l
S
e
a
r
c
h
P
h
a
s
e
1798) consumeResult:385, InitialSearchPhase
1798)consumeResult:385,InitialSearchPhaseArraySearchPhaseResults (org.elasticsearch.action.search)
lambda$innerOnResponse$0:223, InitialSearchPhase$2 (org.elasticsearch.action.search)
access$200:50, InitialSearchPhase (org.elasticsearch.action.search)
onShardResult:250, InitialSearchPhase (org.elasticsearch.action.search)
11.AbstractSearchAsyncAction
onShardSuccess:230, AbstractSearchAsyncAction (org.elasticsearch.action.search)
收集返回结果
本过程在search线程池中执行:
private void onShardResult (FirstResult result, SearchShardIterator shardIt) {
onShardSuccess(result);
success fulShardExecution(shardIt);
}
onShardSuccess对收集到的结果进行合并。successfulShardExecution方法检查是否所有请求都已收到回复,是否进入
private void successfulShardExecution (SearchShardIterator shardsIt) {
//计数器累加.
final int xTotalOps = totalOps.addAndGet (remainingOpsOnIterator);
//检查是否收到全部回复
if (xTotalOps == expectedTotalOps) {
onPhaseDone ();
} else if (xTota1Ops > expectedTotal0ps) {
throw new AssertionError(. ..);
}
}
12.返回InitialSearchPhase
successfulShardExecution:269, InitialSearchPhase (org.elasticsearch.action.search)
13.AbstractSearchAsyncAction
onPhaseDone:248, AbstractSearchAsyncAction (org.elasticsearch.action.search)
executeNextPhase:139, AbstractSearchAsyncAction (org.elasticsearch.action.search)
executePhase:145, AbstractSearchAsyncAction (org.elasticsearch.action.search)
下一步:执行SearchPhase
private void executePhase(SearchPhase phase) {
try {
phase.run();
} catch (Exception e) {
}
doRun:88, FetchSearchPhase$1 (org.elasticsearch.action.search)
@Override
public void run() throws IOException {
context.execute(new ActionRunnable<SearchResponse>(context) {
@Override
public void doRun() throws IOException {
// we do the heavy lifting in this inner run method where we reduce aggs etc. that's why we fork this phase
// off immediately instead of forking when we send back the response to the user since there we only need
// to merge together the fetched results which is a linear operation.
innerRun();
}
});
}
access$000:46, FetchSearchPhase (org.elasticsearch.action.search)
innerRun:106, FetchSearchPhase (org.elasticsearch.action.search)
收集结果
收集器的定义在innerRun中,包括收到的shard数据存放在哪里,收集完成后谁来处理:
final CountedCollector<FetchSearchResult> counter = new CountedCollector<>
(r -> fetchResults.set(r.getShardIndex(),r), docIdsToLoad.length, finishPhase,context);
fetchResults用于存储从某个shard 收集到的结果,每收到一个shard 的数据就执行一次 counter.countDown()。当所有shard数据收集完毕后,countDown 会出触发执行finishPhase:
final Runnable finishPhase = () -> moveToNextPhase(searchPhaseController, scrollId,
reducedQueryPhase, queryAndFetchOptimization ? queryResults : fetchResults);
moveToNextPhase方法执行下一阶段,下-阶段要执行的任务定义在FetchSearchPhase构造 函数中,主要是触发ExpandSearchPhase:
FetchSearchPhase(InitialSearchPhase.SearchPhaseResults<SearchPhaseResult> resultConsumer, SearchPhaseController searchPhaseController, SearchPhaseContext context) {
this(resul tConsumer, searchPhaseController, context,(response, scrollId) -> newExpandSearchPhase(context, response,
// collapse only happens if the request has inner hits
(finalResponse)->sendResponsePhase(finalResponse, scrollId, context)));
}