ESソースの学習の--Get APIの実現ロジック


Github上のesプロジェクトは、その使いやすさを説明する際に、ESの開梱すなわち使用する特性を例に挙げて説明します。使うのはGet APIです。フラグメントの摘出は以下の通りである
--     
curl -XPUT 'http://localhost:9200/twitter/doc/1?pretty' -H 'Content-Type: application/json' -d '
{
    "user": "kimchy",
    "post_date": "2009-11-15×××3:12:00",
    "message": "Trying out Elasticsearch, so far so good?"
}'

--     
curl -XGET 'http://localhost:9200/twitter/doc/1?pretty=true'
Get APIの通常の用途は2つあります。
2 idに基づいてドキュメント全体の詳細を取得し、検索するためのfetch段階。
ESの内部メカニズムを研究し、Get APIは極めて良い接点である。Get APIを通して知ることができる知識点は、
a.ESのrest appiの実現方式。
b.ESの文書ルーティング方式。
c.ESのRPC実現機構。
d.ESのtranslogs.
e.ESはどうやってluceneのIndexSearcherを使いますか?
f.ESはどのようにIDに基づいてluceneのdoc_idを取得しますか?
g.ESはどのようにしてluceneのdoc_idによって文書の明細を取得しますか?
……
ESの内部メカニズムを研究することは、ESの洪水の力を解放するのに役立つ。例えば、業務によってESのpluginを開発する時、その内部の流れはとても参考になります。内部の詳細が知れば知るほど、ピットを踏みにくいです。
GET APIのコアプロセスは以下の通りである。s1:
  controller.registerHandler()  ,       http   

public class RestGetAction extends BaseRestHandler {

     @Inject
    public RestGetAction(Settings settings, RestController controller, Client client) {
        super(settings, controller, client);
        controller.registerHandler(GET, "/{index}/{type}/{id}", this);
    } 

    @Override
    public void handleRequest(final RestRequest request, final RestChannel channel, final Client client) {
           ...
        client.get(getRequest, new RestBuilderListener(channel) {
            ...
        });
    }
}
s2:
public class NodeClient extends AbstractClient {
    ...
    @Override
    public > 
       void doExecute(Action action, Request request, ActionListener listener) {
        TransportAction transportAction = actions.get(action);
        ...
        transportAction.execute(request, listener);
    }
}

       actions    ,   :
public class ActionModule extends AbstractModule {
    ...

    @Override
    protected void configure() {
        ...
        registerAction(GetAction.INSTANCE, TransportGetAction.class);
        ...
    }
}
s3:
          ,       id,  hash          ShardId,     ShardId   NodeId。 
ES               ,    RoutingTable.   RoutingTable,                ;      Id         Node. 
       ,            :routing preference

public class TransportGetAction extends TransportSingleShardAction {

    ...

    @Override
    protected ShardIterator shards(ClusterState state, InternalRequest request) {
        return clusterService.operationRouting()
                .getShards(clusterService.state(), request.concreteIndex(), request.request().type(), request.request().id(), request.request().routing(), request.request().preference());
    }
}
s4:
     ,   ES RPC  。      NodeId,        NodeId  。
  ES   Node       ,     Node   Server   Client   ,     RPC      。
     transportService.sendRequest()   messageReceived()。 

public abstract class TransportSingleShardAction extends TransportAction {

    class AsyncSingleAction {

        public void start() {
                transportService.sendRequest(clusterService.localNode(), transportShardAction, internalRequest.request(), new BaseTransportResponseHandler() {
                    ...     
                });
        }

    }

    private class ShardTransportHandler extends TransportRequestHandler {

        @Override
        public void messageReceived(final Request request, final TransportChannel channel) throws Exception {

            ...
            Response response = shardOperation(request, request.internalShardId);
            channel.sendResponse(response);
        }
    }

}
s5: id id

       :
step1:  type id       , lucene        lucene doc_id

step2:   doc_id          。

public final class ShardGetService extends AbstractIndexShardComponent {

      ...

    private GetResult innerGet(String type, String id, String[] gFields, boolean realtime, long version, VersionType versionType, FetchSourceContext fetchSourceContext, boolean ignoreErrorsOnGeneratedFields) {
        fetchSourceContext = normalizeFetchSourceContent(fetchSourceContext, gFields);
                ...
                get = indexShard.get(new Engine.Get(realtime, new Term(UidFieldMapper.NAME, Uid.createUidAsBytes(typeX, id)))
                        .version(version).versionType(versionType));

                ...
               innerGetLoadFromStoredFields(type, id, gFields, fetchSourceContext, get, docMapper, ignoreErrorsOnGeneratedFields); 
        }
    }
(注:realtime=trueであれば、trnslogsからsourceを読み取り、読み込まれていない場合はインデックスから読み込む)
s 5は、Luceneの内部実現に関し、ここでは展開しない。
最後にまとめます
Get APIはES内部で流れ全体を貫通する機能点である。機能から見れば、それは十分に簡単です。実現から見て、彼はまたESの主な流れを直列にして、それを切り口として、展示You Know, for SearchRestMainActionのように表面に浮くことはない。検索を実現するインターフェースのように複雑で難解ではないです。