Elasticsearch 面试题

目录

1.为什么要使用 Elasticsearch?

2.Elasticsearch 的 master 选举流程?

3.Elasticsearch 集群脑裂问题?

脑裂问题是什么?

脑裂问题可能的成因:

 脑裂问题解决方案:

4.Elasticsearch  索引文档的流程?

5.Elasticsearch 更新和删除文档的流程?

6.Elasticsearch 搜索的流程?

Query阶段

Fetch阶段

 需要两个阶段才能完成搜索的原因

7.Elasticsearch  在部署时,对 Linux 的设置有哪些优化方法? 

补充:索引阶段性能提升方法

8.在并发情况下,Elasticsearch  如何保证读写一致?

9.监控 Elasticsearch  集群状态?

10. Elasticsearch  中的集群、节点、索引、文档、类型是什么?

11.Elasticsearch  中的倒排索引是什么?


1.为什么要使用 Elasticsearch?

系统中的数据,随着业务的发展,时间的推移,将会非常多,而业务中往往采用模糊查询进行数据的搜索,而模糊查询会导致查询引擎放弃索引,导致系统查询数据时都是全表扫描,在百万级别的数据库中,查询效率是非常低下的,而我们使用 ES 做一个全文索引,将经常查询的系统功能的某些字段,比如说电商系统的商品表中商品名,描述、价格还有 id 这些字段我们放入 ES 索引里,可以提高查询速度。

2.Elasticsearch 的 master 选举流程?

1)对所有可以成为 master 的节点(node.master: true)根据 nodeId 字典排序,每次选举每个节点都把自己所知道节点排一次序,然后选出第一个(第 0 位)节点,暂且认为它是master 节点。
2)如果对某个节点的投票数达到一定的值(可以成为 master 节点数 n/2+1)并且该节点自己也选举自己,那这个节点就是 master。否则重新选举一直到满足上述条件。

master 节点的职责主要包括集群、节点和索引的管理,不负责文档级别的管理;data 节点可以关闭 http功能。

3.Elasticsearch 集群脑裂问题?

脑裂问题是什么?

不同的节点对master节点的选择出现了异常——也就是所谓的脑裂问题。

脑裂问题可能的成因:

  • 网络问题:集群间的网络延迟导致一些节点访问不到 master,认为 master 挂掉了从而选举出新的master,并对 master 上的分片和副本标红,分配新的主分片。
  • 节点负载:主节点的角色既为 master 又为 data,访问量较大时可能会导致 ES 停止响应造成大面积延迟,此时其他节点得不到主节点的响应认为主节点挂掉了,会重新选取主点。
  • 内存回收:data 节点上的 ES 进程占用的内存较大,引发 JVM 的大规模内存回收,造成 ES 进程失去响应。

 脑裂问题解决方案:

  • 减少误判:discovery.zen.ping_timeout 节点状态的响应时间,默认为 3s,可以适当调大,如果 master在该响应时间的范围内没有做出响应应答,判断该节点已经挂掉了。调大参数(如 6s,discovery.zen.ping_timeout:6),可适当减少误判。
  • 选举触发:discovery.zen.minimum_master_nodes:1,该参数是用于控制选举行为发生的最小集群主节点数量。当备选主节点的个数大于等于该参数的值,且备选主节点中有该参数个节点认为主节点挂了,进行选举。官方建议为(n/2)+1,n 为主节点个数(即有资格成为主节点的节点个数)
  • 角色分离:即 master 节点与 data 节点分离,限制角色主节点配置为:node.master: true node.data: false,从节点配置为:node.master: false node.data: true

4.Elasticsearch  索引文档的流程?

  1. 协调节点默认使用文档 ID 参与计算(也支持通过 routing),以便为路由提供合适的分片:shard = hash(document_id) % (num_of_primary_shards)
  2. 当分片所在的节点接收到来自协调节点的请求后,会将请求写入到 内存,然后定时(默认是每隔 1 秒)写入到 文件系统缓冲区。
  3.  当然在某些情况下,存在内存和文件系统缓冲区 的数据可能会丢失,ES 是通过 translog的机制来保证数据的可靠性的。其实现机制是接收到请求后,同时也会写入到 translog 中,当 文件系统缓冲区中的数据写入到磁盘中时,才会清除掉。
  4. 在 flush 过程中,内存中的缓冲将被清除,内容被写入一个新段,段的 fsync 将创建一个新的提交点,并将内容刷新到磁盘,旧的 translog 将被删除并开始一个新的 translog。
  5. flush 触发的时机是定时触发(默认 30 分钟)或者 translog 变得太大(默认为 512M)时;

5.Elasticsearch 更新和删除文档的流程?

  1.  删除和更新也都是写操作,但是 Elasticsearch 中的文档是不可变的,因此不能被删除或者改动以展示其变更;
  2. 磁盘上的每个段都有一个相应的.del 文件。当删除请求发送后,文档并没有真的被删除,而是在.del文件中被标记为删除。该文档依然能匹配查询,但是会在结果中被过滤掉。当段合并时,在.del 文件中被标记为删除的文档将不会被写入新段。
  3. 在新的文档被创建时,Elasticsearch 会为该文档指定一个版本号,当执行更新时,旧版本的文档在.del文件中被标记为删除,新版本的文档被索引到一个新段。旧版本的文档依然能匹配查询,但是会在结果中被过滤掉。

6.Elasticsearch 搜索的流程?

搜索被执行成一个两阶段过程,我们称之为 Query Then Fetch;

Query阶段

在初始查询阶段,查询会广播到索引中每一个分片副本(主分片或副分片)。每个分片在本地执行搜索并构建一个匹配文档的优先队列。优先队列是一个存有topN匹配文档的有序列表。优先队列大小为分页参数from + size。

查询阶段步骤如下:

1)客户端发送search请求到NODE 3。
2)Node 3将查询请求转发到索引的每个主分片或副分片中。
3)每个分片在本地执行查询,并使用本地的Term/Document Frequency信息进行打分,添加结果到大小为from + size的本地有序优先队列中。
4)每个分片返回各自优先队列中所有文档的ID和排序值给协调节点,协调节点合并这些值到自己的优先队列中,产生一个全局排序后的列表。

Fetch阶段

Query阶段知道了要取哪些数据,但是并没有取具体的数据,这就是Fetch阶段要做的。

 

Fetch阶段由以下步骤构成:

  1. 协调节点向相关NODE发送GET请求。
  2. 分片所在节点向协调节点返回数据。
  3. 协调节点等待所有文档被取得,然后返回给客户端。

分片所在节点在返回文档数据时,处理有可能出现的_source字段和高亮参数。

协调节点首先决定哪些文档“确实”需要被取回,例如,如果查询指定了{ "from": 90, "size":10 },则只有从第91个开始的10个结果需要被取回。为了避免在协调节点中创建的number_of_shards * (from + size)优先队列过大,应尽量控制分页深度。

 需要两个阶段才能完成搜索的原因

在查询的时候不知道文档位于哪个分片,因此索引的所有分片(某个副本)都要参与搜索,然后协调节点将结果合并,再根据文档ID获取文档内容。例如,有5个分片,查询返回前10个匹配度最高的文档,那么每个分片都查询出当前分片的TOP 10,协调节点将5×10 = 50的结果再次排序,返回最终TOP 10的结果给客户端。

7.Elasticsearch  在部署时,对 Linux 的设置有哪些优化方法? 

  • Elasticsearch 默认被配置为使用单播发现,以防止节点无意中加入集群。只有在同一台机器上运行的节点才会自动组成集群。最好使用单播代替组播。
  • 把你的内存的(少于)一半给 Lucene(但不要超过 32 GB!)
  • 如果你要在更快的 CPUs 和更多的核心之间选择,选择更多的核心更好。多个内核提供的额外并发远胜过稍微快一点点的时钟频率。

补充:索引阶段性能提升方法

  • 使用批量请求并调整其大小:每次批量数据 5–15 MB 大是个不错的起始点。
  • 增加 index.translog.flush_threshold_size 设置,从默认的 512 MB 到更大一些的值,比如 1
    GB,这可以在一次清空触发的时候在事务日志里积累出更大的段。
  • 如果你的搜索结果不需要近实时的准确度,考虑把每个索引的 index.refresh_interval 改到 30s。
  • 如果你在做大批量导入,考虑通过设置 index.number_of_replicas: 0 关闭副本。

8.在并发情况下,Elasticsearch  如何保证读写一致?

  • 可以通过版本号使用乐观并发控制,以确保新版本不会被旧版本覆盖。
  • 另外对于写操作,一致性级别支持 quorum/one/all,默认为 quorum,即只有当大多数分片可用时才允许写操作。但即使大多数可用,也可能存在因为网络等原因导致写入副本失败,这样该副本被认为故障,分片将会在一个不同的节点上重建。
  • 对于读操作,可以设置 replication 为 sync(默认是同步),这使得操作在主分片和副本分片都完成后才会返回;如果设置 replication 为 async 时,也可以通过设置搜索请求参数_preference 为 primary 来查询主分片,确保文档是最新版本。

9.监控 Elasticsearch  集群状态?

  • elasticsearch-head 插件
  • 通过 Kibana 监控 Elasticsearch。你可以实时查看你的集群健康状态和性能,也可以分析过去的集群、索引和节点指标

10. Elasticsearch  中的集群、节点、索引、文档、类型是什么?

  • 集群是一个或多个节点(服务器)的集合,它们共同保存您的整个数据,并提供跨所有节点的联合索引和搜索功能。集群由唯一名称标识,默认情况下为“elasticsearch”。此名称很重要,因为如果节点设置为按名称加入集群,则该节点只能是集群的一部分。
  • 节点是属于集群一部分的单个服务器。它存储数据并参与群集索引和搜索功能。
  • 索引就像关系数据库中的“数据库”。它有一个定义多种类型的映射。索引是逻辑名称空间,映射到一个或多个主分片,并且可以有零个或多个副本分片。
  • 文档类似于关系数据库中的一行。不同之处在于索引中的每个文档可以具有不同的结构(字段),但是对于通用字段应该具有相同的数据类型。 
  • 类型是索引的逻辑类别/分区,其语义完全取决于用户。

11.Elasticsearch  中的倒排索引是什么?

搜索引擎的主要目标是在查找发生搜索条件的文档时提供快速搜索。ES中的倒排索引其实就是 lucene 的倒排索引,区别于传统的正向索引,倒排索引会在存储数据时将关键词和数据进行关联,保存到倒排表中,然后查询时,将查询内容进行分词后在倒排表中进行查询,最后匹配数
据即可。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小鲁蛋儿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值