一个搜索请求必须询问请求的索引中所有分片的某个副本来进行匹配。
假设一个索引有5个主分片,每个主分片有1个副分片,共10个分片,一次搜索请求会由5个分片来共同完成,它们可能是主分片,也可能是副分片。也就是说,一次搜索请求只会命中所有分片副本中的一个。
协调节点
两阶段:查询(Query)阶段和取回(Fetch)阶段。
在初始查询阶段,查询会广播到索引中每一个分片副本(主分片或副分片),每个分片在本地执行搜索并构建一个匹配文档的、存有topN匹配文档的有序列表优先队列,大小为分页参数from +size。
Query阶段
- 客户端发送search请求到NODE 3
- Node 3将查询请求转发到索引的每个主分片或副分片中。
- 每个分片在本地执行查询,并使用本地的Term/Document Frequency信息进行打分,添加结果到大小为from + size的本地有序优先队列中。
- 每个分片返回各自优先队列中所有文档的ID和排序值给协调节点,协调节点合并这些值到自己的优先队列中,产生一个全局排序后的列表。
更详细的Query流程如下
Fetch阶段
- 协调节点向相关NODE发送GET请求。
- 分片所在节点向协调节点返回数据
- 协调节点等待所有文档被取得,会按照返回的排序值对从所有分片取回的值重新进行排序,最终只选取客户端需要的from+size个文档的Id,然后返回给客户端。
更详细的Fetch流程如下
ElasticSearch的分布式查询流程分为query和fetch两个阶段,在query阶段会从所有的shard上读取相关document的docId及相关的排序字段值,并最终在coordinating节点上收集所有的结果数进入一个全局的排序列表后,然后获取根据from+size指定page页的数据,获取这些docId后再构建一个multi-get请求发送相关的shard上从_source里面获取需要加载的数据,最终再返回给client端,至此整个search请求流程执行完毕