ES查询内核流程

举报
xxlla 发表于 2020/11/07 14:49:54 2020/11/07
【摘要】 1 概述 ES查询分为GET和SEARCH两类,GET查询指定_index,_type,_id,从正排索引中获取指定Doc。SEARCH查询不指定_id,根据关键字从倒排索引中获取内容。以下主要分析SEARCH过程:(1) SEARCH过程分为两个阶段:Query和Fetch。(2) SEARCH过程涉及两类节点:协调节点和数据节点。Query阶段客户端将请求发送给协调...

1     概述

  ES查询分为GETSEARCH两类,GET查询指定_index_type_id,从正排索引中获取指定DocSEARCH查询不指定_id,根据关键字从倒排索引中获取内容。以下主要分析SEARCH过程:

(1)    SEARCH过程分为两个阶段:QueryFetch

(2)    SEARCH过程涉及两类节点:协调节点和数据节点。

Query阶段客户端将请求发送给协调节点,协调节点将请求转发到数据节点上索引的每个主分片或副本分片中,每个分片在本地执行查询,并进行打分,添加结果到大小为from+size的本地有序优先队列中。每个分片返回各自优先队列中所有文档的ID和排序值给协调节点,协调节点合并这些值到自己的优先队列中,产生一个全局排序后的列表。

Fetch阶段根据Query阶段的结果,协调节点向相关数据节点发送GET请求,分片所在节点向协调节点返回数据,协调节点等待所有文档被取得,然后返回给客户端。

2     源码分析

2.1      协调节点流程

2.1.1        Query阶段:

1.解析请求

RestSearchAction#prepareRequest方法中将请求体解析为SearchRequest数据结构:

    image.png

2.构造目的shard列表

将请求涉及的本集群shard列表和远程集群的shard列表合并,TransportSearchAction#executeSearch完成了合并操作,调用了mergeShardIterators

    image.png

    

3.遍历所有shard发送请求

请求是基于shard遍历的,如果列表中有Nshard位于同一个节点,则向其发送N次请求。AbstractSearchAsyncAction#run完成此操作,        performPhaseOnShard发送请求:

    image.png

    

4.收集返回结果

AbstractSearchAsyncAction#onShardResult完成收集操作,consumeResult对收集的结果进行合并:

    image.png

successfulShardException检查是否所有请求都已收到回复,是否进入下一阶段:

    image.png

以上方法调用的OnPhaseDone方法会调用executeNextPhase,从而开始执行Fetch取回阶段。

2.1.2        Fetch阶段:

1.     发送Fetch请求

Query阶段的executeNextPhrase方法触发Fetch阶段,Fetch阶段的起点为FetchSearchPharse#innerRun函数,再进一步调用executeFetch方法,从查询阶段的shard列表中遍历来获取数据。

executeFetch的主要实现:

            image.png

executeFetch中定义一个Listener,每成功获取一个shard数据后就执行counter.onResult,其中调用对结果的处理回调,把result保存到数组中,然后执行countDown:

            image.png

2.     收集结果

收集器定义在innerRun中,包括收到的shard数据存放在哪里,收集完成后谁来处理:

            image.png

            

fetchResults用于存储从某个shard收集到的结果,每收到一个shard的数据就执行一次counter.countDown。当所有shard数据收集完毕后,countDown会触发执行finishPhase:

            image.png

            

moveToNextPhase方法执行下一阶段,下一阶段要执行的任务定义在FetchSearchPhase构造函数中,主要是触发ExpandSearchPharse,取回阶段完成之后执行ExpandSearchPharse#run,主要判断是否启用字段叠加,根据需要实现字段叠加功能。

3.     回复客户端

ExpandSearchPharse执行完之后回复客户端,在sendResonsePharse方法中实现:

            image.png

2.3      数据节点流程

2.2.1        响应Query请求

主要过程就是执行查询,然后发送ResponseQueryFetch请求的处理入口注册于SearchTransportService#registerRequestHandler:

            image.png

            

查询入口在searchService.executeQueryPhase中。查询时,先看是否允许cache,由以下配置决定:

index.requests.cache.enable

默认为true,会把查询结果放到cache中,查询时优先从cache中取。这个cache由节点的所有分片共享,基于LRU算法实现:空间满的时候删除最近最少使用的数据。所以cache并不缓存全局检索结果。

       核心的查询封装在queryPhase.execute(context)中,其中调用Lucene实现检索,同时实现聚合:

            image.png

            

其中包含几个核心功能:

executeInternal():调用Lucenesearcher.search()实现搜索;

rescoreRhase:全文检索且需要打分;

suggestPhase:自动补全及纠错;

aggregationPhase:实现聚合。

2.2.2        响应Fetch请求

  主要过程是执行Fetch,然后发送Response

        image.png

        

Fetch响应的实现封装在searchService.executeFetrchPhase中,核心是调用fetchPhase.execute(context)。按照命中的doc取得相关数据,填充到SearchHits中,最终封装到FetchSearchResult

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。