Elastic Search的基础概念

Posted by KANG's BLOG on Tuesday, March 15, 2022

ES是基于lucene的

其对Lucene 做了一层封装,它提供了一套简单一致的 RESTful API 来帮助我们实现存储和检索。

核心概念

1. Cluster:集群

ES可以作为一个独立的单个搜索服务器。不过,为了处理大型数据集,实现容错和高可用性,ES可以运行在许多互相合作的服务器上。这些服务器的集合称为集群。

2. Node:节点

形成集群的每个服务器称为节点。

3. Shard:分片

当有大量的文档时,由于内存的限制、磁盘处理能力不足、无法足够快的响应客户端的请求等,一个节点可能不够。这种情况下,数据可以分为较小的分片。每个分片放到不同的服务器上。 当你查询的索引分布在多个分片上时,ES会把查询发送给每个相关的分片,并将结果组合在一起,而应用程序并不知道分片的存在。即:这个过程对用户来说是透明的。

4. Replia:副本

为提高查询吞吐量或实现高可用性,可以使用分片副本。 副本是一个分片的精确复制,每个分片可以有零个或多个副本。ES中可以有许多相同的分片,其中之一被选择更改索引操作,这种特殊的分片称为主分片。 当主分片丢失时,如:该分片所在的数据不可用时,集群将副本提升为新的主分片。

5. 全文检索

全文检索就是对一篇文章进行索引,可以根据关键字搜索,类似于mysql里的like语句。 全文索引就是把内容根据词的意义进行分词,然后分别创建索引,例如”你们的激情是因为什么事情来的” 可能会被分词成:“你们“,”激情“,“什么事情“,”来“ 等token,这样当你搜索“你们” 或者 “激情” 都会把这句搜出来。

查询类型

1. query and fetch

向索引的所有分片 ( shard)都发出查询请求, 各分片返回的时候把元素文档 ( document)和计算后的排名信息一起返回。

这种搜索方式是最快的。 因为相比下面的几种搜索方式, 这种查询方法只需要去 shard查询一次。 但是各个 shard 返回的结果的数量之和可能是用户要求的 size 的 n 倍。

2. query then fetch(默认)

  1. 发送查询到每个shard
  2. 找到所有匹配的文档,并使用本地的Term/Document Frequency信息进行打分
  3. 对结果构建一个优先队列(排序,标页等)
  4. 返回关于结果的元数据到请求节点注意,实际文档还没有发送,只是分数
  5. 来自所有shard的分数合并起来,并在请求节点上进行排序,文档被按照查询要求进行选择
  6. 最终,实际文档从他们各自所在的独立的shard上检索出来
  7. 结果被返回给用户

3. dfs query and fetch

  1. 预查询每个shard,询问Term和Document frequency
  2. 发送查询到每个shard
  3. 找到所有匹配的文档,并使用全局的Term/Document Frequency信息进行打分
  4. 对结果构建一个优先队列(排序,标页等)
  5. 返回关于结果的元数据到请求节点注意,实际文档还没有发送,只是分数
  6. 来自所有shard的分数合并起来,并在请求节点上进行排序,文档被按照查询要求进行选择
  7. 最终,实际文档从他们各自所在的独立的shard上检索出来
  8. 结果被返回给用户

4. dfs query then fetch

  1. 预查询每个shard,询问Term和Document frequency
  2. 发送查询到每个shard
  3. 找到所有匹配的文档,并使用全局的Term/Document Frequency信息进行打分
  4. 对结果构建一个优先队列(排序,标页等)
  5. 返回关于结果的元数据到请求节点注意,实际文档还没有发送,只是分数
  6. 来自所有shard的分数合并起来,并在请求节点上进行排序,文档被按照查询要求进行选择
  7. 最终,实际文档从他们各自所在的独立的shard上检索出来
  8. 结果被返回给用户

DFS 是一个什么样的过程?

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