Elasticsearch-29-搜索原理内核解析

query phase

假设我们有一个index里面的数据分布在3个primary shard上(对应的replica也有),现在总共有7个shard,我们现在要搜索这个index中的数据的第10000条到10010条.如图所示
phase1

请求发送给某一个shard时,这个shard就是coordinate node, coordinate node会构建一个 priority queue,队列长度是查询时的from和size的和,默认是0 + 10 = 10;

我们要查询的是10000-10010条数据,所以请求的from = 9999,size = 10,这个时候coordinate node会在它本地建立一个长度是 9999 + 10 = 10009 的 priority queue, 然后coordinate node将请求打到其他的shard上去

phase2

接收到请求的每个shard,也会在本地建立一个 from + size大小的priority queue,每个shard将自己下标是0 - 10009的数据放到这个队列中, 也就是10010条数据,返回给coordinate node.
phase3

coordinate node 将返回的所有数据进行合并,合并成一份from * size大小的priority queue,全局排序后,放到自己队列中去

phase4

最后在自己的队列中取出当前要获取的那一页的数据.

这里也可以看出我们之前提到过的deep paging问题,就是说,from * size分页太深,那么每个shard都要返回大量的数据给coordinate node,消耗大量的带宽,内存, CPU

fetch phase

在上面的query phase的工作处理完成之后,coordinate node 在priority queue里面找到了需要的数据, 但是其实这个队列时存的document的id, 这个时候,coordinate node就发送mget请求(批量查询)到所有shard上去获取对应的document

phase6

然后各个shard将document返回给coordinate node, coordinate node将合并后的document结果返回给客户端

phase7

bouncing results问题

比如说有两个document,field值相同;但是分布在不同的shard上面,在不同的shard上可能排序也不相同, 每次请求轮询打到不同的shard上去,页面上看到的搜索结果的排序可能都不一样, 这就是 bouncing results,也就是跳跃的结果.

preference

preference 决定了哪些shard会执行搜索请求.

bouncing results问题解决

将preference设置为一个字符串,比如说user_id,让每个user每次搜索的时候,都使用同一个shard去执行,就不会看到bouncing results了