[源码解析] elastic search 8.0.0 的查询原理(一)

本文深入探讨了Elasticsearch 8.0.0的查询过程,从任务封装到异步执行,包括请求链验证、拦截器过滤、索引名称解析、分片路由和线程池的使用。特别指出,查询操作涉及多个线程池,如系统内置索引和用户自定义索引的查询使用不同线程池,并分析了搜索请求在集群中的执行流程。
摘要由CSDN通过智能技术生成

每个查询请求都是先将request封装为一个task,然后再异步执行,如下所示

public <Request extends ActionRequest, Response extends ActionResponse>
    Task registerAndExecute(String type, TransportAction<Request, Response> action, Request request,
                            BiConsumer<Task, Response> onResponse, BiConsumer<Task, Exception> onFailure) {
         //1 来一个请求,会生成一个task
        final Task task;
        try {
            task = register(type, action.actionName, request);
        } catch (TaskCancelledException e) {
            unregisterChildNode.close();
            throw e;
        }
         //2 task 生成完后,会根据action的类型找对应的实现类真正执行
        action.execute(task, request, new ActionListener<Response>() {
            @Override
            public void onResponse(Response response) {
                try {
                    Releasables.close(unregisterChildNode, () -> unregister(task));
                } finally {
                    onResponse.accept(task, response);
                }
            }

             
        });
        return task;
    }

进入execute之后,具体过程如下。

经过一个请求链的验证

RequestFilterChain<Request, Response> requestFilterChain = new RequestFilterChain<>(this, logger);
        requestFilterChain.proceed(task, actionName, request, listener);
@Override
        public void proceed(Task task, String actionName, Request request, ActionListener<Response> listener) {
            int i = index.getAndIncrement();
            try {
                //1、2个拦截器进行各自的验证
                if (i < this.action.filters.length) {
                    this.action.filters[i].apply(task, actionName, request, listener, this);
                //2、通过后开始执行
                } else if (i == this.action.filters.length) {
                    this.action.doExecute(task, request, listener);
                } else {
                    listener.onFailure(new IllegalStateException("proceed was called too many times"));
                }
            } catch(Exception e) {
                logger.trace("Error during transport action execution.", e);
                listener.onFailure(e);
            }
        }

上面是模板方法设计模式,先用拦截器过滤一遍,看是否符合要求的action

在上面代码的第一步中,涉及到的具体的拦截器实例是下面这2个

第一个

第二个

在执行doExecute的时候就会到了Action真正的实现类去执行。在文档查询里面是TransportSearchAction

@Override
    protected void doExecute(Task task, SearchRequest searchRequest, ActionListener<SearchResponse> listener) {
//1、会对其他集群的索引和当前集群的索引分组
final Map<String, OriginalIndices> remoteClusterIndices = remoteClusterService.groupIndices(searchRequest.indicesOptions(),
                searchRequest.indices());
}


重点方法executeSearch。由于该方法很长,接下来分段解析。

private void executeSearch(SearchTask task, SearchTimeProvider timeProvider, SearchRequest searchRequest,
                               OriginalIndices localIndices, List<SearchShardIterator> remoteShardIterators,
                               BiFunction<String, String, DiscoveryNode> remoteConnections, ClusterState clusterState,
                               Map<String, AliasFilter> remoteAliasMap, ActionListener<SearchResponse> listener,
                               SearchResponse.Clusters clusters) {
1 集群的状态是否可用,是有有异常

clusterState.blocks().globalBlockedRaiseException(ClusterBlockLevel.READ);
2 解析索引名称 正常的别名或者索引es不允许以_开始

final Index[] indices = resolveLocalIndices(localIndices, clusterState, timeProvider);
3、构建别名过滤器 如果是内部索引查询比如.ml-config,是获取不到任何的别名过滤器的
Map<String, AliasFilter> aliasFilter = buildPerIndexAliasFilter(searchRequest, clusterState, indices, remoteAliasMap);
4、路由的处理
Map<String, Set<String>> routingMap = indexName
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值