本篇文章为大家带来ES面试指南,题目大部分来自于网络上,有小部分是来自于工作中的总结,每个题目会给出一个参考答案,希望对大家面试大数据分析师能够有所帮助。
为什么考察Elasticsearch?
为什么考察Elasticsearch?
Elasticsearch是一个近实时的搜索平台,在大数据生态系统中占据重要的地位。我们必须要了解其基本原理和概念,一方面可以对数据分析工作中排查问题有比较大的帮助,另一方面方便我们与他人沟通交流。
请介绍下ES以及其特性和应用场景?
Elasticsearch是一个基于Lucene的开源分布式搜索引擎,具有分布式多用户能力,基于RESTful web接口。能够达到实时搜索、高性能计算;同时Elasticsearch的横向扩展能力非常强,不需要重启服务,基本上达到了零配置。可以应用在搜索引擎、日志数据分析、全文检索、结构化检索等场景。 详细描述一下Elasticsearch删除和更新文档的过程。 磁盘上的每个段都有一个相应的.del文件。当删除请求发送后,文档并没有真的被删除,而是在.del文件中被标记为删除。该文档依然能匹配查询,但是会在结果中被过滤掉。当段合并时,在.del文件中被标记为删除的文档将不会被写入新段。 在新的文档被创建时,Elasticsearch会为该文档指定一个版本号,当执行更新时,旧版本的文档在.del文件中被标记为删除,新版本的文档被索引到一个新段。旧版本的文档依然能匹配查询,但是会在结果中被过滤掉。 在并发情况下,Elasticsearch如何保证读写一致? 可以通过版本号使用乐观并发控制,以确保新版本不会被旧版本覆盖,由应用层来处理具体的冲突; 另外对于写操作,一致性级别支持quorum/one/all,默认为quorum,即只有当大多数分片可用时才允许写操作。但即使大多数可用,也可能存在因为网络等原因导致写入副本失败,这样该副本被认为故障,分片将会在一个不同的节点上重建。 对于读操作,可以设置replication为sync(默认),这使得操作在主分片和副本分片都完成后才会返回;如果设置replication为async时,也可以通过设置搜索请求参数_preference为primary来查询主分片,确保文档是最新版本。 索引层面调优手段有哪些? 设计阶段调优 1)根据业务增量需求,采取基于日期模板创建索引,通过roll over API滚动索引; 2)使用别名进行索引管理; 3)每天凌晨定时对索引做force_merge操作,以释放空间; 4)采取冷热分离机制,热数据存储到SSD,提高检索效率;冷数据定期进行shrink操作,以缩减存储; 5)采取curator进行索引的生命周期管理; 6)仅针对需要分词的字段,合理的设置分词器; 7)Mapping阶段充分结合各个字段的属性,是否需要检索、是否需要存储等。 写入调优 1)写入前副本数设置为0; 2)写入前关闭refresh_interval设置为-1,禁用刷新机制; 3)写入过程中:采取bulk批量写入; 4)写入后恢复副本数和刷新间隔; 5)尽量使用自动生成的id。 查询调优 1)禁用wildcard; 2)禁用批量terms(成百上千的场景); 3)充分利用倒排索引机制,能使用keyword类型尽量使用keyword; 4)数据量大的场景,可以先基于时间确定索引再检索; 5)设置合理的路由机制。 为什么使用ES查询快? 因为使用了倒排索引的技术:一般我们都是这样定义id关键词,倒排索引是关键词id正好相反,使用索引工具进行查询时,首先得到关键词,建立倒排索引表,关键词--索引列表包含该关键词所在的文档的id、在该文档中出现的次数、在该文档中出现的位置信息,这种由属性值确定记录的位置的方式称为倒排索引。还有索引库中的词都是按照顺序排列,后期根据一个关键词查询的时候,可以利用类似折半查找的算法,查询效率非常高。 ES几种查询方式的对比 _local:查询操作首先在本地查找,如果本地没有再到其他节点进行查找; _primary:只在主分片中查询; _shads:按照指定的分片进行查询,这种查询方式实现了es的极速查询。 ES写数据的执行流程? 客户端选择一个node发送请求过去,该node就是coordinating node(协调节点); coordinating node对document进行路由,将请求转发给对应的node(有primary shard); 实际的node上的primary shard处理请求,然后将数据同步到replica node; coordinating node若发现primary node和所有replica node都响应完操作后,就返回结果给客户端。 ES读数据的执行流程
查询,GET某一条数据,写入了某个document,该document会自动给你分配一个全局唯一id-doc id,同时也是根据doc id进行hash路由到对应的primary shard上面去。也可以手动指定doc id,比如用订单id,用户id。 可以通过doc id来查询,会根据doc id进行hash,判断出当时把doc id分配到了哪个shard,从那个shard去查询。 客户端发送请求到任意一个node,成为coordinate node; coordinate node对document路由,将请求转发到对应的node,此时会使用round-robin随机轮询算法,在primary shard及其所有replica中随机选择,使读请求负载均衡; 接收请求的node返回document给coordinate node; coordinate node返回document给客户端; Elasticssearch的倒排索引是什么? 参考答案: 倒排索引是搜索引擎最常用的存储方式,在搜索引擎的实际应用中,有时需要按照关键字的某些值查找记录,这种按照关键字建立索引被称为倒排索引。 索引是用于提高查询效率的。举个最简单的例子,已知有5个文本文件,需要我们去查某个单词位于哪个文本文件中,最直观的做法就是逐个加载每个文本文件到内存中,然后用for循环遍历,直到找到这个单词,这种做法就是正向索引的思路。而倒排索引的做法是先将文件进行分词,分别以单词作为索引,对应的值就是文件,通过这个索引就可以直接找到文件。 倒排索引的优点还包括在处理复杂的多关键字查询时,可在倒排表中先完成查询的并、交等逻辑运算,得到结果后再对记录进行存取,这样把对文档的查询转换为地址集合的运算,从而提高查找速度。 详细描述一下Elasticsearch搜索的过程? 参考答案:搜索分为”query“和“fetch”两个阶段: 1)在初始查询阶段时,查询会广播到索引中每一个分片拷贝(主分片或者副本分片)。 每个分片在本地执行搜索并构建一个匹配文档的优先队列。每个分片返回各自优先队列中所有文档的ID和排序值给协调节点,它合并这些值到自己的优先队列中来产生一个全局排序后的结果列表。 2)接下来就是取回阶段,协调节点辨别出哪些文档需要被取回并向相关的分片提交多个 GET 请求。每个分片加载并丰富文档,如果有需要的话,接着返回文档给协调节点。一旦所有的文档都被取回了,协调节点返回结果给客户端。 核心概念(什么是集群、分片、重新分布、自动发现机制、交互方式)
集群(Cluster): 包含一个或多个具有相同 cluster.name 的节点。集群内节点协同工作,共享数据,并共同分担工作负荷。由于节点是从属集群的,集群会自我重组来均匀地分发数据。 节点(node): 一个节点是一个逻辑上独立的服务,可以存储数据,并参与集群的索引和搜索功能, 一个节点也有唯一的名字,群集通过节点名称进行管理和通信。 索引(Index): 索引与关系型数据库实例(Database)相当。索引只是一个 逻辑命名空间,它指向一个或多个分片(shards)。 文档类型(Type):相当于数据库中的table概念。每个文档在ElasticSearch中都必须设定它的类型。 文档(Document) :相当于数据库中的row, 是可以被索引的基本单位。文档是以JSON格式存储的。在一个索引中,您可以存储多个的文档。 Mapping: 相当于数据库中的schema,用来约束字段的类型,不过 Elasticsearch 的 mapping 可以自动根据数据创建。 分片(shard) :是 工作单元(worker unit) 底层的一员,用来分配集群中的数据,它只负责保存索引中所有数据的一小片。分片是一个独立的Lucene实例,并且它自身也是一个完整的搜索引擎。文档存储并且被索引在分片中,但是我们的程序并不会直接与它们通信。取而代之,它们直接与索引进行通信的。把分片想象成一个数据的容器。数据被存储在分片中,然后分片又被分配在集群的节点上。 分片分为 主分片(primary shard) 以及 从分片(replica shard) 两种。在你的索引中,每一个文档都属于一个主分片。从分片只是主分片的一个副本,它用于提供数据的冗余副本,在硬件故障时提供数据保护,同时服务于搜索和检索这种只读请求。索引中的主分片的数量在索引创建后就固定下来了,但是从分片的数量可以随时改变。一个索引默认设置了5个主分片,每个主分片有一个从分片对应。 数据重新分布(recovery):es在有节点加入或退出时会根据机器的负载对索引分片进行重新分配,挂掉的节点重新启动时也会进行数据恢复。 自动发现机制(discovery.zen):es是一个基于p2p的系统,它先通过广播寻找存在的节点,再通过多播协议来进行节点之间的通信,同时也支持点对点的交互。 集群或节点与客户端交互的方式(Transport):默认内部是使用tcp协议进行交互,同时它支持http协议(json格式)、thrift、servlet、memcached、zeroMQ等的传输协议(通过插件方式集成)。 搜索类型有哪些?介绍一下 es在查询时,可以指定搜索类型为QUERY_THEN_FETCH,QUERY_AND_FEATCH,DFS_QUERY_THEN_FEATCH和DFS_QUERY_AND_FEATCH。 我们以查询匹配度最高的Top10为例,讲解下他们的区别。 1)QUERY_AND_FETCH 1:客户端把请求发送给集群中的某一个节点,这个节点会把查询请求发送给所有分片去执行, 2:每个分片会把查询的数据(包含数据的分值,以及数据的详细内容)返回给某一个节点进行汇总,排序,然后把这些数据返回给客户端。 这样客户端可能会收到(10*分片数量)的数据 这种方案,数据量和排名都有问题。 优点:效率高,查询速度快 2)QUERY_THEN_FETCH(默认) 1:客户端把请求发送给集群中的某一个节点,这个节点会把查询请求发送给所有分片去执行, 2:每个分片会把查询的数据(包含数据的分值,以及数据ID)返回给某一个节点进行汇总,排序,取前10名 3:根据前10名的id到对应的分片查询数据的详细内容,返回给客户端 这种方案,解决了数据量的问题,但是排名可能还有问题。 3)DFS_QUERY_AND_FETCH(DFS:初始化散发过程) 1:在查询之前,会把所有分片的词频和文档频率(打分依据)汇总到一块 2:客户端把请求发送给集群中的某一个节点,这个节点会把查询请求发送给所有分片去执行 3:每个分片会把查询的数据(包含数据的分值,以及数据的详细内容)返回给某一个节点进行汇总,排序,然后把这些数据返回给客户端 解决了排名的问题,还存在数据量的问题 4)DFS_QUERY_THEN_FETCH 1:在查询之前,会把所有分片的词频和文档频率(打分依据)汇总到一块 2:客户端把请求发送给集群中的某一个节点,这个节点会把查询请求发送给所有分片去执行, 3:每个分片会把查询的数据(包含数据的分值,以及数据ID)返回给某一个节点进行汇总,排序,取前10名 4:根据前10名的id到对应的分片查询数据的详细内容,返回给客户端。 既解决了排名问题,也解决了数据量的问题,但是性能最低。 总结一下,从性能考虑QUERY_AND_FETCH是最快的,DFS_QUERY_THEN_FETCH是最慢的。从搜索的准确度来说,DFS要比非DFS的准确度更高。 setting与mapping作用? settings修改索引库默认配置,比如分片数量、副本数量; mapping非常类似于静态语言中的数据类型:声明一个变量为int类型的变量, 以后这个变量都只能存储int类型的数据。同样的, 一个number类型的mapping字段只能存储number类型的数据。不过,除了定义类型外,mapping还可以定义是否分词、分词方式、日期格式等信息。
注释:本文来自公众号大数据与人工智能
大数据培训:http://www.baizhiedu.com/bigdata2019