ElasticSearch搜索引擎常见⾯试题总结
⼀、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怎么改写reference
(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、doc_values 的作⽤:
倒排索引也是有缺陷的,假如我们需要对数据做⼀些排序或聚合操作时,lucene 内部会遍历提取所有出现在⽂档集合的排序字段,然后再次构建⼀个最终的排好序的⽂档集合list,这个步骤的过程全部维持在内存中操作,⽽且如果排序数据量巨⼤的话,⾮常容易就造成内存溢出和性能缓慢。
doc_values 就是 es 在构建倒排索引的同时,构建了正排索引,保存了docId到各个字段值的映射,可以看作是以⽂档为维度,从⽽实现根据指定字段进⾏排序和聚合的功能。另外 doc_values 保存在操作系统的磁盘中,当 doc_values ⼤于节点的可⽤内存,ES可以从操作系统页缓存中加载或弹出,从⽽避免发⽣内存溢出的异常,docValues远⼩于节点的可⽤内存,操作系统⾃然将所有 doc_values 存于内存中(堆外内存),有助于快速访问。
更多 doc_values 的介绍与使⽤欢迎阅读这篇⽂章:
5、text 和 keyword类型的区别:
matlab指数函数怎么表示两个的区别主要分词的区别:keyword 类型是不会分词的,直接根据字符串内容建⽴倒排索引,keyword类型的字段只能通过精确值搜索到;Text 类型在存⼊ Elasticsearch 的时候,会先分词,然后根据分词后的内容建⽴倒排索引
6、什么是停顿词过滤:
停顿词可以看成是没有意义的词,⽐如“的”、“⽽”,这类词没有必要建⽴索引
7、query 和 filter 的区别?
trunc函数mysql
(1)query:查询操作不仅仅会进⾏查询,还会计算分值,⽤于确定相关度;
(2)filter:查询操作仅判断是否满⾜查询条件,不会计算任何分值,也不会关⼼返回的排序问题,同时,filter 查询的结果可以被缓存,提⾼性能。
⼆、ES的写⼊流程:
1、es 写数据的过程:
2、写数据的底层原理:
mysql面试题集合
(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操作。
更多 ES 的数据写⼊流程的说明欢迎阅读这篇⽂章:
三、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 ⽂件
有关segment段合并过程,欢迎阅读这篇⽂章:
四、ES的搜索流程:
搜索被执⾏成⼀个两阶段过程,即 Query Then Fetch:
1、Query阶段:
客户端发送请求到 coordinate node,协调节点将搜索请求⼴播到所有的 primary shard 或 replica shard。每个分⽚在本地执⾏搜索并构建⼀个匹配⽂档的⼤⼩为 from + size 的优先队列。 每个分⽚返回各⾃优先队列中 所有⽂档的 ID 和排序值 给协调节点,由协调节点及逆⾏数据的合并、排序、分页等操作,产出最终结果。
2、Fetch阶段:
协调节点根据 doc id 去各个节点上查询实际的 document 数据,由协调节点返回结果给客户端。
css实现轮播图自动切换
Query Then Fetch 的搜索类型在⽂档相关性打分的时候参考的是本分⽚的数据,这样在⽂档数量较少的时候可能不够准确,DFS Query Then Fetch 增加了⼀个预查询的处理,询问 Term 和 Document frequency,这个评分更准确,但是性能会变差。
五、ES在⾼并发下如何保证读写⼀致性?
(1)对于更新操作:可以通过版本号使⽤乐观并发控制,以确保新版本不会被旧版本覆盖
每个⽂档都有⼀个_version 版本号,这个版本号在⽂档被改变时加⼀。Elasticsearch使⽤这个 _version 保证所有修改都被正确排序。当⼀个旧版本出现在新版本之后,它会被简单的忽略。
利⽤_version的这⼀优点确保数据不会因为修改冲突⽽丢失。⽐如指定⽂档的version来做更改。如果那个版本号不是现在的,我们的请求就失败了。
(2)对于写操作,⼀致性级别⽀持 quorum/one/all,默认为 quorum,即只有当⼤多数分⽚可⽤时才允许写操作。但即使⼤多数可⽤,也可能存在因为⽹络等原因导致写⼊副本失败,这样该副本被认为故障,分⽚将会在⼀个不同的节点上重建。
(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通)这两部分;
补充:master节点的职责主要包括集、节点和索引的管理,不负责⽂档级别的管理;data节点可以关闭http功能。
3、Elasticsearch是如何避免脑裂现象:
(1)当集中 master 候选节点数量不⼩于3个时(node.master: true),可以通过设置最少投票通过数量
(inimum_master_nodes),设置超过所有候选节点⼀半以上来解决脑裂问题,即设置为 (N/2)+1;
(2)当集 master 候选节点 只有两个时,这种情况是不合理的,最好把另外⼀个node.master改成false。如果我们不改节点设置,还是套上⾯的(N/2)+1公式,此时inimum_master_nodes应该设置为2。这就出现⼀个问题,两个master备选节点,只要有⼀个挂,就选不出master了
七、建⽴索引阶段性能提升⽅法:
java语言代码基础
⼋、ES的深度分页与滚动搜索scroll
(1)深度分页:
深度分页其实就是搜索的深浅度,⽐如第1页,第2页,第10页,第20页,是⽐较浅的;第10000页,第20000页就是很深了。搜索得太深,就会造成性能问题,会耗费内存和占⽤cpu。⽽且es为了性能,他不⽀持超过⼀万条数据以上的分页查询。那么如何解决深度分页带来的问题,我们应该避免深度分页操作(限制分页页数),⽐如最多只能提供100页的展⽰,从第101页开始就没了,毕竟⽤户也不会搜的那么深。
(2)滚动搜索:
⼀次性查询1万+数据,往往会造成性能影响,因为数据量太多了。这个时候可以使⽤滚动搜索,也就是 scroll。 滚动搜索可以先查询出⼀些数据,然后再紧接着依次往下查询。在第⼀次查询的时候会有⼀个滚动id,相当于⼀个锚标记 ,随后再次滚动搜索会需要上⼀次搜索滚动id,根据这个进⾏下⼀次的搜索请求。每次搜索都是基于⼀个历史的数据快照,查询数据的期间,如果有数据变更,那么和搜索是没有关系的。
相关阅读:

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。