Elasticsearch核心技术与实战学习笔记 41 | 剖析分布式查询及相关性算分

一 序

    本文属于极客时间Elasticsearch核心技术与实战学习笔记系列。

二 分布式搜索的运行机制

  • ES 的搜索,会分两阶段进行
    • 第一阶段 - QUERY
    • 第二阶段 - Fetch
  • Query - then - Fetch

2.1 Query 阶段

    用户发出搜索请求到 ES 节点。节点收到请求后,会以 Coordinating 节点的身份,在 6 个主副分片中随机选择 3 个分片,发送查询请求
被选中的分片执行查询,进行排序。然后,每个分片都会返回 From + Size 个排序后的文档 Id 和排序值给 Coordinating 节点

   

2.2 Fetch 阶段

Coordinating Node 会将 Query 阶段,从每个分片获取的排序后的文档 Id 列表,重新进行排序。选取 From 到 From + Size 个文档的 Id
以 multi get 请求的方式,到相应的分片获取详细的文档数据。   

2.3 Query Then Fetch 潜在的问题

 性能问题

  • 每个分片上需要查的文档个数 = from + size
  • 最终协调节点需要处理:number_of_shard * (from + size)
  • 深度分页

相关性算分

  • 每个分片都基于自己的分片上的数据进行相关度计算。这会导致打分偏离的情况,特别是数据量很少时,如果文档总数很少的情况下,如果主分片大于 1,主分片越多,相关性算分会越不准。

2.4 解决算分不准的方法

 数据量不大的时候,可以将主分片数设置为 1
当数据量足够大时候,只要保证文档均匀分散在各个分片上,结果一般就不会出现偏差
使用 DFS Query Then Fetch
搜索的 URL 中指定参数 “_search?search_type=dfs_query_then_fetch”
到每个分片把各分片的词频和文档频率进行搜集,然后完整的进行一次相关性算分,消耗更加多的 CPU 和内存,执行性能低下,一般不建议使用

3. demo:

数据准备:

DELETE message

POST message/_doc?routing=1
{
  "content":"good"
}

POST message/_doc?routing=2
{
  "content":"good morning"
}

POST message/_doc?routing=3
{
  "content":"good morning everyone"
}
POST message/_search
{
  "query": {
    "term": {
      "content": {
        "value": "good"
      }
    }
  }
}

使用es7  默认1 个主分片测试,不存在分布式查询算分不准的情况,Good 应该排在第一 

 

改为20分片:打分是一样的。

如果使用explain查看,会发现文档分散到不同的shard上,所以分数一样。

如果执行 DFS Query Then Fetch ,结果和一个分片上一致

猜你喜欢

转载自blog.csdn.net/bohu83/article/details/106964379
41