ES面试题

一、ElasticSearch基础

1、什么是Elasticsearch

分布式实时全文搜索引擎(每个字段都被索引并可被搜索)

全文检索是指对每一个词建立一个索引,指明该词在文章中出现的次数和位置。当查询时,根据事先建立的索引进行查找,并将查找的结果反馈给用户的检索方式。这个过程类似于通过字典中的检索字表查字的过程。


2、基本概念

(1)index 索引:索引类似于mysql 中的数据库,存放数据的地方,包含了一堆有相似结构的文档数据。

(2)type 类型:用来定义数据结构,可以认为是 mysql 中的一张表,type 是 index 中的一个逻辑数据分类

(3)document 文档:类似于 MySQL 中的一行,不同之处在于 ES 中的每个文档可以有不同的字段,但是对于通用字段应该具有相同的数据类型,文档是es中的最小数据单元,可以认为一个文档就是一条记录。

(4)Field 字段:Field是Elasticsearch的最小单位,一个document里面有多个field

(5)shard 分片:es可以将一个索引中的数据切分为多个shard,分布在多台服务器上存储。

(6)replica 副本:任何一个服务器随时可能故障或宕机,此时 shard 可能会丢失,因此可以为每个 shard 创建多个 replica 副本。replica可以在shard故障时提供备用服务,保证数据不丢失,多个replica还可以提升搜索操作的吞吐量和性能。primary shard(建立索引时一次设置,不能修改,默认5个),replica shard(随时修改数量,默认1个),默认每个索引10个 shard,5个primary shard,5个replica shard,最小的高可用配置,是2台服务器。

(7)分词器(Tokenizer):将文本数据分成一个个词语的工具。ES内置了多种分词器,如标准分词器、简单分词器、路径分词器等,同时也支持自定义分词器。

(8)映射(Mapping):描述文档数据结构。定义了每个字段的数据类型、分词器、索引方式等属性


3、什么是倒排索引:

关键词(字段值)到文档id的映射

例如,某个文档经过分词,提取了 20 个关键词,每个关键词都会记录它在文档中出现的次数和出现位置。

每个关键词都对应着一系列的文件,这些文件中都出现了该关键词。

要注意倒排索引的两个重要细节:

  • 倒排索引中的所有词项对应一个或多个文档
  • 倒排索引中的词项 根据字典顺序升序排列

4、DocValues的作用:

文档id到关键词(字段值)的映射

用途:

  • 聚合(如分组):例如根据某一个/多个字段进行分组,必须要知道每个文档中该字段对应的值是什么才能进行分组

  • 排序:例如根据一个/多个字段进行排序,必须要通过文档来知道字段值才能进行排序

  • 某些过滤,比如地理位置过滤

  • 某些与字段相关的脚本计算

总结:任何需要通过文档来获取文档内部字段具体值的操作都依赖DocValues.

原理:

  • DocValues 就是 es 在构建倒排索引时创建,可以指定某字段是否开启或关闭DocValues

  • DocValues 保存在操作系统的磁盘中

  • 当docValues大于节点的可用内存,ES可以从操作系统页缓存中加载或弹出,从而避免发生内存溢出的异常

  • 当docValues远小于节点的可用内存,操作系统自然将所有Doc Values存于内存中(堆外内存),有助于快速访问


5、text 和 keyword类型的区别:

两个的区别主要分词的区别:

keyword 类型不会分词

Text 类型先分词然后根据分词后的内容建立倒排索引


6、什么是停顿词过滤:

停顿词可以看成是没有意义的词,比如“的”、“而”,这类词没有必要建立索引


7、query 和 filter 的区别?

filter的作用

通过不同的过滤类型来过滤文档

比如范围过滤(range)、存在过滤(exists)、缺失过滤(missing)等

过滤器不会计算文档的相关性得分,通常用于需要根据数值、日期等非文本内容进行筛选的场景

因为不需要计算相关性得分,所以在性能方面通常比查询更快

query的作用

用来搜索匹配特定条件的文档

比如匹配查询(match)、短语查询(phrase)、前缀查询(prefix)等

查询会计算文档的相关性得分,根据相关性得分进行排序并返回结果

查询通常用于需要根据文本内容进行搜索的场景。

相关性得分如何计算?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
计算分值的过程可以简单的描述为以下几个步骤:

1. 对查询进行分析,将查询语句转换为一个查询对象(query object)。

2. 对每个文档进行评分,计算文档与查询的相关性得分。相关性得分是一个浮点数,表示文档与查询的匹配程度。

3. 将文档按照相关性得分进行排序,得分高的文档排在前面。


使用BM25算法进行分值计算,该算法是一种基于词频和文档长度的统计算法,它会考虑查询词在文档中出现的频率以及文档的长度,来计算文档与查询的相关性得分。

BM25算法的计算过程比较复杂,但可以简单的概括为以下几个步骤:

1. 计算查询词的逆文档频率(inverse document frequency,IDF)。它的值越小表示查询词越常见,对应的文档相关性得分应该越低。

2. 计算查询词在文档中出现的频率(term frequency,TF)。TF表示查询词在文档中出现的次数,它的值越大表示文档与查询的匹配程度越高,对应的文档相关性得分应该越高。

3. 计算文档长度的影响。文档长度越长,查询词在其中出现的次数就越多,需要进行适当的调整。

4. 综合考虑IDF、TF和文档长度的影响,计算文档与查询的相关性得分。



二、ES的写入流程

1、es 写数据的过程

(1)客户端请求发送至协调节点

(2)协调节点进行路由,转发给对应的node

(3)对应node主节点处理,并将处理结果同步给副本

(4)主节点和副本节点都都执行成功之后,就返回响应结果给客户端


2、写数据的底层原理

(1)refresh(刷新)的过程

数据写入–>memory buffer–(每隔1s)–>segment+Filesystem cache+清空memory buffer

数据被 refresh 到 Filesystem cache 之后才能被搜索到,每秒一次,所以是近实时性

(2)translog用途

用于记录所有的写入操作,在服务器宕机时恢复数据

默认每隔 5 秒刷一次到磁盘中,如果此时机器宕机,会丢失 5 秒钟的数据

(3)flush (冲洗)操作

translog 文件超过 512M或者到达30分钟时执行flush操作

  • 先执行refresh
  • 将 Filesystem Cache 中所有的数据都 fsync 到磁盘文件中
  • 删除旧的 translog 日志文件并创建一个新的 translog 日志文件


三、ES的更新和删除流程

es文档是不可变的,因此删除和更新都是写操作

ES 利用 .del 文件标记文档是否被删除

(1)删除操作是在 .del 文件中被标记为 deleted 状态。该文档依然能匹配查询,但是会在结果中被过滤掉

(2)更新操作,就是将旧的 doc 标识为 deleted 状态,然后创建一个新的 doc



四、ES的搜索流程

搜索被执行成一个两阶段过程,即 Query Then Fetch:

1、Query阶段

  • 客户端发送请求到协调节点
  • 协调节点将搜索请求广播到所有的 primary shard 或 replica shard
  • 每个分片返回查询结果(文档ID和排序值)给协调节点
  • 协调节点进行数据的合并、排序、分页等操作

2、Fetch阶段

协调节点根据文档id去查询文档数据,并将返回结果给客户端

协调节点对文档id进行哈希路由,将请求转发到对应的 node,使用随机轮询算法,在主副分片中随机选择一个



五、ES在高并发下如何保证读写一致性

(1)对于写操作

  • one:要求只要有一个主分片是可用的就可以执行

  • all:要求所有对主副分片都是可用的才可以执行

  • quorum:默认的值,要求大多数分片是可用的才可以执行

(2)对于更新操作:采用乐观锁控制版本号实现

(3)对于读操作

可以设置 replication(复制) 为 sync(默认),这使得操作在主分片和副本分片都完成后才会返回

如果设置replication 为 async 时,也可以通过设置搜索请求参数_preference 为 primary 来查询主分片,确保文档是最新版本。



六、ES分布式原理

1、分布式原理

1
2
3
4
5
6
7
8
9
10
11
12
13
1. 分片机制:将索引划分为多个分片,每个分片可以分布在不同的节点上,可以提高数据的可用性和可扩展性

2. 副本机制:将每个分片复制到多个节点上,可以提高读取性能

3. 路由机制:分片路由机制是通过哈希算法实现的。具体来说,当一个文档被索引时,ES会根据文档的ID计算哈希值,并将该哈希值与分片数取模得到一个分片编号,从而确定该文档应该存储在哪个分片中

4. 节点发现和协调机制:
通过Zen Discovery实现节点发现
通过节点之间不间断的互相通信确保整个集群中的节点信息实现同步

5. 负载均衡机制:可以自动将搜索请求和写入请求分发到集群中的各个节点上

6. 故障转移和恢复机制:当某个节点发生故障或不可用时,自动将该节点的分片和副本转移到其他节点上,并恢复数据的一致性。

2、如何选举 Master

集群中可以有多个候选节点,当多数候选节点确认集群中没有master节点时可以发起master选举

通过ZenDiscovery来实现,确保节点间互相通信达到节点信息在集群内的同步

  • 设置候选主节点的最少投票通过数量
  • 选举节点对所有候选节点根据节点Id 排序,第一位的暂且认为它是master节点
  • 如果对某个节点的投票数达到阈值,并且该节点自己也选举自己,那这个节点就是master。否则重新选举一直到满足上述条件。

master节点的作用是什么?

1
2
3
4
5
6
1. 索引管理:创建、删除、分配和重分配等操作,以及Shard的分配和副本的配置

2. 节点管理:加入、离开、状态变化等操作

3. 集群状态管理:全局状态和元数据,包括集群的健康状态、节点状态、索引状态等信息。


3、如何避免脑裂现象

(1)当集群中 master 候选节点数量不小于3个时,可以通过设置最少投票通过数量,设置超过所有候选节点一半以上来解决脑裂问题,即设置为 (N/2)+1

(2)当集群 master 候选节点 只有两个时,这种情况是不合理的,最好把另外一个node.master改成false。



七、建立索引阶段性能提升方法

1
2
3
4
5
6
7
8
9
1. 硬件优化:升级cpu、内存、硬盘等

2. Shard优化:调整数量和大小,大小应该控制在几百MB到几GB之间

3. 索引设计:使用合适的数据类型、分词器和映射等

5. 查询优化:使用更简单的查询语句、减少查询结果的数量、使用聚合查询等方法

6. 网络优化:增加带宽、减少网络延迟等


八、ES的深度分页与scroll

什么是深度分页?

跳过大量数据来查询更深的数据,这就涉及到大量数据的扫描,性能很低


深度分页的常见方案from+size

from表示从什么位置开始取值,size表示取值数量

这种方案的问题是当from+size>10000时将报错,也就是说只能查询前一万条数据

每次查询时from前的条目也会被搜索,极大浪费系统资源


searchAfter

以数值类型且具备唯一性的字段作为排序字段(放在sort中),每次查询携带上次查询的最后一条数据的排序字段值(放在search_after),从而实现分页.

优点:效率比from+size高

缺点:

1、由于需要sort排序,所以每次查询依然会扫描docvalue,因此搜索越深效率越低

2、只能一页一页翻,不能挑页

3、对排序字段有要求,并不是所有排序字段都能分页


scroll游标

它允许我们在处理大量数据时,持续地获取结果,而不必一次性获取所有结果。其原理如下:

1、第一次发送请求携带scroll参数和查询条件(1m表示有效期1分钟)

1
2
3
4
5
6
7
8
POST /my-index-000001/_search?scroll=1m
{
"query": {
"match": {
"message": "foo"
}
}
}

2、第一次查询结果携带scroll_id,用于标识此次查询结果集(相当于es保存了查询结果快照)

3、下次查询只需要携带scroll_id和查询条件,ES会返回下一批结果

4、这样不断循环,直到获取到所有查询结果为止

5、当我们完成查询时,需要发送一个清除scroll请求,以释放资源

原理是在查询时生成ScrollContext对象

1
2
3
4
5
6
public final class ScrollContext {
public TotalHits totalHits = null;
public float maxScore = Float.NaN;
public ScoreDoc lastEmittedDoc;
public Scroll scroll;
}

其中有个关键变量lastEmittedDoc,这个记录了上次scroll遍历到的docId位置,也就是借助这个字段实现深度查询

缺点:非实时、大量数据搜索/下载、不支持跳页



参考资料:

[1]https://segmentfault.com/a/1190000042029202

[2]https://zhuanlan.zhihu.com/p/231790621




版权声明:本文为博主原创文章,欢迎转载,转载请注明作者、原文超链接,感谢各位看官!!!

本文出自:monkeyGeek

座右铭:生于忧患,死于安乐

欢迎志同道合的朋友一起交流、探讨!

monkeyGeek
#

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×