ES查询流程图解与思考

时间:2024-05-19 07:59:47

1.ES有那些搜索方式?

Elasticsearch的搜索类型(SearchType类型)

1、 query and fetch
  向索引的所有分片 ( shard)都发出查询请求, 各分片返回的时候把元素文档 ( document)和计算后的排名信息一起返回。
  这种搜索方式是最快的。 因为相比下面的几种搜索方式, 这种查询方法只需要去 shard查询一次。 但是各个 shard 返回的结果的数量之和可能是用户要求的 size 的 n 倍。
  优点:这种搜索方式是最快的。因为相比后面的几种es的搜索方式,这种查询方法只需要去shard查询一次。
  缺点:返回的数据量不准确, 可能返回(N*分片数量)的数据并且数据排名也不准确,同时各个shard返回的结果的数量之和可能是用户要求的size的n倍。

 

2、 query then fetch(es 默认的搜索方式)
  如果你搜索时, 没有指定搜索方式, 就是使用的这种搜索方式。 这种搜索方式, 大概分两个步骤:
  第一步, 先向所有的 shard 发出请求, 各分片只返回文档 id(注意, 不包括文档 document)和排名相关的信息(也就是文档对应的分值), 然后按照各分片返回的文档的分数进行重新排序和排名, 取前 size 个文档。
  第二步, 根据文档 id 去相关的 shard 取 document。 这种方式返回的 document 数量与用户要求的大小是相等的。
  优点:返回的数据量是准确的。
  缺点:性能一般,并且数据排名不准确。
 

3、 DFS query and fetch
  这种方式比第一种方式多了一个 DFS 步骤,可以更精确控制搜索打分和排名。也就是在进行查询之前,先对所有分片发送请求, 把所有分片中的词频和文档频率等打分依据全部汇总到一块,再执行后面的操作。
  优点:数据排名准确
  缺点:
    性能一般
    返回的数据量不准确, 可能返回(N*分片数量)的数据

 

4、 DFS query then fetch
  比第 2 种方式多了一个 DFS 步骤。
  也就是在进行查询之前, 先对所有分片发送请求, 把所有分片中的词频和文档频率等打分依据全部汇总到一块, 再执行后面的操作、

  优点
    返回的数据量是准确的
    数据排名准确
  缺点
    性能最差【 这个最差只是表示在这四种查询方式中性能最慢, 也不至于不能忍受,如果对查询性能要求不是非常高, 而对查询准确度要求比较高的时候可以考虑这个】
 

 

2.DFS 是一个什么样的过程?
  

      DFS 其实就是在进行真正的查询之前, 先把各个分片的词频率和文档频率收集一下, 然后进行词搜索的时候, 各分片依据全局的词频率和文档频率进行搜索和排名。 显然如果使用 DFS_QUERY_THEN_FETCH 这种查询方式, 效率是最低的,因为一个搜索, 可能要请求 3 次分片。 但, 使用 DFS 方法, 搜索精度是最高的。

 

3.性能方面总结一下?

从性能考虑 QUERY_AND_FETCH 是最快的DFS_QUERY_THEN_FETCH 是最慢的

从搜索的准确度来说, DFS 要比非 DFS 的准确度更高。

ES查询流程图解与思考

 

4.权衡问题思考?根据不同的需求--->定制化选择

1.ES的分片机制天生支持分布式,同时也带来了分布式了弊端:排序和算分问题;

想要精确的算分和排序--->需要大量的计算

2.kafka与ES面临相同的问题:kafka的单个分区内可以保证顺序性,分区之间是不能保证顺序性的

3.搜索的场景需要严格的定制化,通过对mapping的修改可以支持算分的调整,影响查询的结果-----代价是大大增加开发和mapping的维护成本

4.分布式的系统中路由算法的弊端:增加/删除节点时会有路由错误的问题(引发类似于缓存雪崩的场景)

对应的解决方案:如redis的一致性hash算法

ES同样面临类似的场景:每个index的主分片设置策略,动态分配会有大量的数据迁移,分配不合理又会影响性能

对此,ES的解决方案是:index建立好之后不允重新设置分片,需要重新设置需要reindex