読者です 読者をやめる 読者になる 読者になる

Elasticsearchのコードを読んでみる① 検索編

検索のリクエストを受けてからレスポンスを返すまでざっくり追ってみた。
過去何回か追ってみて、時間が経つとすぐ忘れちゃうので備忘録的ななにか。


検索リクエスト処理

RestSearchAction : 検索リクエストを処理する
- client.search NodeClient#search()を実行。いろいろまわってNodeClient#execute()が実行される。


NodeClient : 各ノード内部の検索リクエストを実行するクライアントクラス
- transportAction.execute TransportSearchAction#execute()を実行している。


TransportSearchAction : ノード間で分散検索を行うためのクラス
- doExecute()が実行される。
- 検索タイプによって処理が分かれる。デフォルトでqueryThenFetch(検索後にFetch)。TransportSearchQueryThenFetchAction#execute()が実行される。


TransportSearchQueryThenFetchAction : queryThenFetchを処理するクラス
- doExecute()が実行される。
- AsyncAction#start()を実行。検索対象がなければここでレスポンス返す。


AsyncAction : 各シャードへのリクエストを行う。
- コンストラクタで対象シャードを作成
- startで各シャード毎に処理する。
- performFirstPhase() sendExecuteFirstPhase()でシャードごとに検索処理。SearchServiceTransportAction#sendExecuteQuery()を実行。


SearchServiceTransportAction : 検索通信のためのクラス
- sendExecuteQueryでクエリーを送信。
- 対象シャードがローカルノードなら自ノードのスレッドプールからスレッドを立ち上げてSearchService#executeQueryPhase()を実行。
- 対象シャー度が他ノードなら対象ノードへリクエストを送信する(TransportService#sendRequest())。 対象ノードでSearchQueryTransportHandlerでリクエストを受け、SearchService#executeQueryPhase()を実行。結果を返す。
- 検索が完了したらlistenerに結果を渡す。


SearchService : 検索とか実行するクラス
- LuceneのIndexSearcherなどつかってごにょごにょ


TransportSearchQueryThenFetchAction
- listenerで結果を受け取り、onFirstPhaseResultで処理。全ノードからレスポンスを受けたらmoveToSecondPhase()を実行して次フェース(Fetch)へ移行。
- SearchServiceTransportAction#sendExecuteFetch()を実行してFetchする。


SearchServiceTransportAction
- SearchService#executeFetchPhase()を実行する。(対象が自ノードなら別スレッド、他ノードならリクエストする)
- 完了したらlistenerに結果を渡す。


TransportSearchQueryThenFetchAction
- listenerで結果を受け取り、全シャードを処理し終えたらfinishHimを実行。
- 検索スレッドプールでマージ(SearchPhaseController#merge())。
- 結果をlistener(RestActionから受け取ったActionListener)に渡す。


RestStatusToXContentListener : RestActionで渡されるListenerクラス
- SearchResponseをいい感じにJsonに直してレスポンスを返す。


めでたしめでたし