关于elasticsearch:ElasticSearch常见面试题汇总

37次阅读

共计 6589 个字符,预计需要花费 17 分钟才能阅读完成。

一、ElasticSearch 根底:

1、什么是 Elasticsearch:

Elasticsearch 是基于 Lucene 的 Restful 的分布式实时全文搜索引擎,每个字段都被索引并可被搜寻,能够疾速存储、搜寻、剖析海量的数据。

全文检索是指对每一个词建设一个索引,指明该词在文章中呈现的次数和地位。当查问时,依据当时建设的索引进行查找,并将查找的后果反馈给用户的检索形式。这个过程相似于通过字典中的检索字表查字的过程。

2、Elasticsearch 的基本概念:

(1)index 索引:索引相似于 mysql 中的数据库,Elasticesearch 中的索引是存在数据的中央,蕴含了一堆有类似构造的文档数据。

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

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

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

(5)shard 分片:单台机器无奈存储大量数据,es 能够将一个索引中的数据切分为多个 shard,散布在多台服务器上存储。有了 shard 就能够横向扩大,存储更多数据,让搜寻和剖析等操作散布到多台服务器下来执行,晋升吞吐量和性能。

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

3、什么是倒排索引:

在搜索引擎中,每个文档都有一个对应的文档 ID,文档内容被示意为一系列关键词的汇合。例如,某个文档通过分词,提取了 20 个关键词,每个关键词都会记录它在文档中呈现的次数和呈现地位。那么,倒排索引就是 关键词到文档 ID 的映射,每个关键词都对应着一系列的文件,这些文件中都呈现了该关键词。有了倒排索引,搜索引擎能够很不便地响应用户的查问。

要留神倒排索引的两个重要细节:

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

4、DocValues 的作用:

倒排索引也是有缺点的,如果咱们须要对数据做一些聚合操作,比方排序 / 分组时,lucene 外部会遍历提取所有呈现在文档汇合的排序字段,而后再次构建一个最终的排好序的文档汇合 list,这个步骤的过程全副维持在内存中操作,而且如果排序数据量微小的话,非常容易就造成 solr 内存溢出和性能迟缓。

DocValues 就是 es 在构建倒排索引的同时,构建了正排索引,保留了 docId 到各个字段值的映射,能够看作是以文档为维度,从而实现依据指定字段进行排序和聚合的性能。

另外 doc Values 保留在操作系统的磁盘中,当 docValues 大于节点的可用内存,ES 能够从操作系统页缓存中加载或弹出,从而防止产生内存溢出的异样,docValues 远小于节点的可用内存,操作系统天然将所有 Doc Values 存于内存中(堆外内存),有助于快速访问。

5、text 和 keyword 类型的区别:

两个的区别次要分词的区别:keyword 类型是不会分词的,间接依据字符串内容建设倒排索引,keyword 类型的字段只能通过准确值搜寻到;Text 类型在存入 Elasticsearch 的时候,会先分词,而后依据分词后的内容建设倒排索引

6、什么是进展词过滤:

进展词能够看成是没有意义的词,比方“的”、“而”,这类词没有必要建设索引

7、query 和 filter 的区别?

(1)query:查问操作不仅仅会进行查问,还会计算分值,用于确定相关度;

(2)filter:查问操作仅判断是否满足查问条件,不会计算任何分值,也不会关怀返回的排序问题,同时,filter 查问的后果能够被缓存,进步性能。

二、ES 的写入流程:

1、es 写数据的过程:

(1)客户端抉择一个 node 发送申请过来,这个 node 就是 coordinating node(协调节点)

(2)coordinating node 对 document 进行路由,将申请转发给对应的 node(有 primary shard)

(3)理论的 node 上的 primary shard 解决申请,而后将数据同步到 replica node

(4)coordinating node 等到 primary node 和所有 replica node 都执行胜利之后,就返回响应后果给客户端。

2、写数据的底层原理:

(1)数据先写入 memory buffer,而后定时(默认每隔 1s)将 memory buffer 中的数据写入一个新的 segment 文件中,并进入 Filesystem cache(同时清空 memory buffer),这个过程就叫做 refresh;

ES 的近实时性:数据存在 memory buffer 时是搜寻不到的,只有数据被 refresh 到 Filesystem cache 之后能力被搜寻到,而 refresh 是每秒一次,所以称 es 是近实时的,能够通过手动调用 es 的 api 触发一次 refresh 操作,让数据马上能够被搜寻到;

(2)因为 memory Buffer 和 Filesystem Cache 都是基于内存,假如服务器宕机,那么数据就会失落,所以 ES 通过 translog 日志文件来保证数据的可靠性,在数据写入 memory buffer 的同时,将数据写入 translog 日志文件中,在机器宕机重启时,es 会主动读取 translog 日志文件中的数据,复原到 memory buffer 和 Filesystem cache 中去。

ES 数据失落的问题:translog 也是先写入 Filesystem cache,而后默认每隔 5 秒刷一次到磁盘中,所以默认状况下,可能有 5 秒的数据会仅仅停留在 memory buffer 或者 translog 文件的 Filesystem cache 中,而不在磁盘上,如果此时机器宕机,会失落 5 秒钟的数据。也能够将 translog 设置成每次写操作必须是间接 fsync 到磁盘,然而性能会差很多。

(3)flush 操作:一直反复下面的步骤,translog 会变得越来越大,当 translog 文件默认每 30 分钟或者 阈值超过 512M 时,就会触发 commit 操作,即 flush 操作。

  • 将 buffer 中的数据 refresh 到 Filesystem Cache 中去,清空 buffer;
  • 创立一个新的 commit point(提交点),同时强行将 Filesystem Cache 中目前所有的数据都 fsync 到磁盘文件中;
  • 删除旧的 translog 日志文件并创立一个新的 translog 日志文件,此时 commit 操作实现

三、ES 的更新和删除流程:

删除和更新都是写操作,然而因为 Elasticsearch 中的文档是不可变的,因而不能被删除或者改变以展现其变更;所以 ES 利用 .del 文件 标记文档是否被删除,磁盘上的每个段都有一个相应的.del 文件

(1)如果是删除操作,文档其实并没有真的被删除,而是在 .del 文件中被标记为 deleted 状态。该文档仍然能匹配查问,然而会在后果中被过滤掉。

(2)如果是更新操作,就是将旧的 doc 标识为 deleted 状态,而后创立一个新的 doc。

memory buffer 每 refresh 一次,就会产生一个 segment 文件,所以默认状况下是 1s 生成一个 segment 文件,这样下来 segment 文件会越来越多,此时会定期执行 merge。

每次 merge 的时候,会将多个 segment 文件合并成一个,同时这里会将标识为 deleted 的 doc 给物理删除掉,不写入到新的 segment 中,而后将新的 segment 文件写入磁盘,这里会写一个 commit point,标识所有新的 segment 文件,而后关上 segment 文件供搜寻应用,同时删除旧的 segment 文件

四、ES 的搜寻流程:

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

1、Query 阶段:

客户端发送申请到 coordinate node,协调节点将搜寻申请播送到所有的 primary shard 或 replica shard。每个分片在本地执行搜寻并构建一个匹配文档的大小为 from + size 的优先队列。每个分片返回各自优先队列中 所有文档的 ID 和排序值 给协调节点,由协调节点及逆行数据的合并、排序、分页等操作,产出最终后果。

2、Fetch 阶段:

协调节点依据 doc id 去各个节点上查问理论的 document 数据,由协调节点返回后果给客户端。

  • coordinate node 对 doc id 进行哈希路由,将申请转发到对应的 node,此时会应用 round-robin 随机轮询算法,在 primary shard 以及其所有 replica 中随机抉择一个,让读申请负载平衡。
  • 接管申请的 node 返回 document 给 coordinate node。
  • coordinate node 返回 document 给客户端。

Query Then Fetch 的搜寻类型在文档相关性打分的时候参考的是本分片的数据,这样在文档数量较少的时候可能不够精确,DFS Query Then Fetch 减少了一个预查问的解决,询问 Term 和 Document frequency,这个评分更精确,然而性能会变差。

举荐:Java 进阶视频资源

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

(1)对于更新操作:能够通过版本号应用乐观并发管制,以确保新版本不会被旧版本笼罩

每个文档都有一个_version 版本号,这个版本号在文档被扭转时加一。Elasticsearch 应用这个 _version 保障所有批改都被正确排序。当一个旧版本呈现在新版本之后,它会被简略的疏忽。

利用 _version 的这一长处确保数据不会因为批改抵触而失落。比方指定文档的 version 来做更改。如果那个版本号不是当初的,咱们的申请就失败了。

(2)对于写操作,一致性级别反对 quorum/one/all,默认为 quorum,即只有当大多数分片可用时才容许写操作。但即便大多数可用,也可能存在因为网络等起因导致写入正本失败,这样该正本被认为故障,分片将会在一个不同的节点上重建。

  • one:要求咱们这个写操作,只有有一个 primary shard 是 active 沉闷可用的,就能够执行
  • all:要求咱们这个写操作,必须所有的 primary shard 和 replica shard 都是沉闷的,才能够执行这个写操作
  • quorum:默认的值,要求所有的 shard 中,必须是大部分的 shard 都是沉闷的,可用的,才能够执行这个写操作

(3)对于读操作,能够设置 replication 为 sync(默认),这使得操作在主分片和正本分片都实现后才会返回;如果设置 replication 为 async 时,也能够通过设置搜寻申请参数_preference 为 primary 来查问主分片,确保文档是最新版本。

六、ES 如何选举 Master 节点:

1、Elasticsearch 的分布式原理:

Elasticsearch 会对存储的数据进行切分,将数据划分到不同的分片上,同时每一个分片会保留多个正本,次要是为了保障分布式环境的高可用。在 Elasticsearch 中,节点是对等的,节点间会选取集群的 Master,由 Master 会负责集群状态信息的扭转,并同步给其余节点。

Elasticsearch 的性能会不会很低:只有建设索引和类型须要通过 Master,数据的写入有一个简略的 Routing 规定,能够路由到集群中的任意节点,所以数据写入压力是扩散在整个集群的。

2、Elasticsearch 如何 选举 Master:

Elasticsearch 的选主是 ZenDiscovery 模块负责的,次要蕴含 Ping(节点之间通过这个 RPC 来发现彼此)和 Unicast(单播模块蕴含一个主机列表以管制哪些节点须要 ping 通)这两局部;

  • 确认候选主节点的起码投票通过数量,elasticsearch.yml 设置的值 discovery.zen.minimum_master_nodes;
  • 对所有候选 master 的节点(node.master: true)依据 nodeId 字典排序,每次选举每个节点都把本人所晓得节点排一秩序,而后选出第一个(第 0 位)节点,暂且认为它是 master 节点。
  • 如果对某个节点的投票数达到阈值,并且该节点本人也选举本人,那这个节点就是 master。否则从新选举始终到满足上述条件。

补充:master 节点的职责次要包含集群、节点和索引的治理,不负责文档级别的治理;data 节点能够敞开 http 性能。

3、Elasticsearch 是如何防止脑裂景象:

(1)当集群中 master 候选节点数量不小于 3 个时(node.master: true),能够通过设置起码投票通过数量(discovery.zen.minimum_master_nodes),设置超过所有候选节点一半以上来解决脑裂问题,即设置为 (N/2)+1

(2)当集群 master 候选节点 只有两个时,这种状况是不合理的,最好把另外一个 node.master 改成 false。如果咱们不改节点设置,还是套下面的 (N/2)+1 公式,此时 discovery.zen.minimum_master_nodes 应该设置为 2。这就呈现一个问题,两个 master 备选节点,只有有一个挂,就选不出 master 了

举荐:Java 进阶视频资源

七、建设索引阶段性能晋升办法:

(1)应用 SSD 存储介质

(2)应用批量申请并调整其大小:每次批量数据 5–15 MB 大是个不错的起始点。

(3)如果你在做大批量导入,思考通过设置 index.number_of_replicas: 0 敞开正本

(4)如果你的搜寻后果不须要近实时的准确度,思考把每个索引的 index.refresh_interval 改到 30s

(5)段和合并:Elasticsearch 默认值是 20 MB/s。但如果用的是 SSD,能够思考进步到 100–200 MB/s。如果你在做批量导入,齐全不在意搜寻,你能够彻底关掉合并限流。

(6)减少 index.translog.flush_threshold_size 设置,从默认的 512 MB 到更大一些的值,比方 1 GB

八、ES 的深度分页与滚动搜寻 scroll

(1)深度分页:

深度分页其实就是搜寻的深浅度,比方第 1 页,第 2 页,第 10 页,第 20 页,是比拟浅的;第 10000 页,第 20000 页就是很深了。搜寻得太深,就会造成性能问题,会消耗内存和占用 cpu。而且 es 为了性能,他不反对超过一万条数据以上的分页查问。

那么如何解决深度分页带来的问题,咱们应该防止深度分页操作(限度分页页数),比方最多只能提供 100 页的展现,从第 101 页开始就没了,毕竟用户也不会搜的那么深。

(2)滚动搜寻:

一次性查问 1 万 + 数据,往往会造成性能影响,因为数据量太多了。这个时候能够应用滚动搜寻,也就是 scroll。滚动搜寻能够先查问出一些数据,而后再紧接着顺次往下查问。

那么如何解决深度分页带来的问题,咱们应该防止深度分页操作(限度分页页数),比方最多只能提供 100 页的展现,从第 101 页开始就没了,毕竟用户也不会搜的那么深。

(2)滚动搜寻:

一次性查问 1 万 + 数据,往往会造成性能影响,因为数据量太多了。这个时候能够应用滚动搜寻,也就是 scroll。滚动搜寻能够先查问出一些数据,而后再紧接着顺次往下查问。

在第一次查问的时候会有一个滚动 id,相当于一个锚标记,随后再次滚动搜寻会须要上一次搜寻滚动 id,依据这个进行下一次的搜寻申请。每次搜寻都是基于一个历史的数据快照,查问数据的期间,如果有数据变更,那么和搜寻是没有关系的。

对于 ElasticSearch 常见面试题,你学废了么?


正文完
 0