ES面试题
1.为什么要使用ES?
系统中的数据,随着业务的发展,时间的推移,将会非常多,而业务中往往采用模糊查询进行数据的搜索,而模糊查询会导致查询引擎放弃索引,导致系统查询数据时全表扫描,在百万级别的数据库中,查询效率是非常低下的,而我们使用ES做一个全文索引,将经常查询的系统功能的某些字段,比如说电商系统的商品表中的商品,描述、价格还有id这些字段我们放入ES索引库里,可以提高查询速度。
2.ES的master选举流程?
1.ES的选举是ZenDiscovery模块负责的,主要包含Ping(节点之间通过找个RPC来发现彼此)和Unicast(单播模块包含一个主机列表以控制哪些节点需要ping通)这个两个部分。
2.对所有可以成为master的节点根据nodeId字典排序,每次选举每个节点,都把自己所知道的节点排一次序,然后选出第一个节点,暂定认为他为master节点。
3.如果对某个节点的投票数达到一定的值并且该节点自己也选举自己,那找个节点就是master。否则重新选举一直到满足上述条件。
4.master结点的职责主要包括集群、节点和索引的管理,不负责文档级别的管理;data节点可以关闭http功能。
3.ES集群脑裂问题?
脑裂:在ES中存在多个master结点之后。
“脑裂”可能造成的原因:
1.网络问题:集群之间的网络延迟导致一些节点访问不到master,认为master挂掉了,从而选举出新的master,并对master上的分片和副本标红,分配新的主分片。
2.节点负载:主节点的角色既为master又为data,访问量较大的时候可能会导致ES停止响应造成大面积延迟,此时其他节点得不到主节点的响应,认为主节点挂掉了,会重新选取主节点。
3.内存回收:data节点上的ES进程占用内存较大,引发JVM大规模内存回收,造成ES进程失去响应。
“脑裂”问题解决方案:
1.减少误判:discovery.zen.ping_timeout节点状态的响应时间,默认是3s,可以适当调大,如果master在该响应时范围内没有做出响应应答,判断该节点已经挂了。因此调大参数,可以适当减少误判。
2.选举触发:discovery.zen.minimum_master_nodes:1 该参数使用户控制选举行为发生的最小集群主节点数量。当备选主节点的个数大于等于该参数的值,且备选主节点中有该参数个节点认为主节点挂了,进行选举。官方建议为(n/2)+1,这时候才有资格成为主节点。
3.角色分离:即master节点与data节点分离,限制角色
主节点配置为:node.master:true node.data:false
从节点配置为:node.master:false nodo.data:true
4.ES索引文档的流程?
客户端向服务器发出索引文档的请求,会根据路由算法,找到主分片的位置,往里面索引数据,同时为了保证数据的一致性,会对副本进行数据同步。
用户发送索引请求后,首先会在内存当中创建一个索引,并且将索引在内存中形成一个分段对象。同时为了防止数据出现问题,会将操作存在内存中的日志。并且每隔一秒钟会将内存中的segement刷到文件系统的缓存中。每隔一段时间,会将文件系统缓存中的segment刷入硬盘中。
5.ES更新和删除文档流程?
1.删除和更新操作都是些操作。由于ES中的文档是不可变的,因此不能被删除或者改动以展示其变更。
2.磁盘上的每个段都有一个对应的.del文件。当删除请求发送后,文档并没有真的被删除,而是在.del文件中被标记为删除。该文档依然能够匹配查询,但是会在结果中被过滤掉。当段合并时,在.del文件中被标记为删除的文档将不会被写入新段。
3.在新的文档被创建的时候,ES会为该文档指定一个版本号,当执行更新操作的时候,旧版本的文档在.del文件中被标记为三处,新本的文档会被索引到一个新段。旧版本的文档依然能匹配查询,但是会在结果中被过滤掉。
6.ES搜索的流程
1.搜索被执行成为一个两阶段过程,我们称之为Query Then Fetch;
2.在初始查询阶段,查询会广播到索引中每一个分片拷贝。每个分片在本地执行搜索并构建一个匹配文档的大小为from+size的优先队列。PS:在搜索的时候是会查询File system Cache的,但是有部分数据还在Memory Buffer,所以搜索是近实时的。
3.每个分片返回各自优先队列中所有文档的ID和排序值给协调节点,它合并这些值到自己的优先队列中来产生一个全局排序后的结果列表。
4.接下来就是取回阶段,协调节点辨别出那些文档需要被取回并向相关的分片提交多个GET请求。每个分片加载并丰富文档,如果有需要的话,接着返回文档给协调节点。一旦所有的文档都被取回了,协调节点返回结果给客户端。
7.GC方面,在使用ES时候需要注意什么?
1.倒排词典的索引需要常驻内存,无法GC,需要监控DataNode上Segment memory增长趋势。
2.各类缓存,field cache,filter cache等等,需要设置合理的大小,并且要应该根据最坏的情况来看heap是否够用。
3.避免返回大量结果集的搜索与聚合。确实需要大量拉取数据的场景,可以采用scan & scroll api来实现。
4.cluster stats驻留在内存并无法水平扩展,超大规模集群可以考虑拆分成多个集群通过tribe node链接。
5.想知道heap够不够,必须结合实际应用场景,并对集群的heap使用情况做持续的监控。
8.在并发情况下,ES如何保证读写一致性的?
1.可以通过版本号使用乐观并发控制,以确保新版本不会被旧版本覆盖,由应用层来处理具体的冲突;
2.另外对于写操作,一致性级别直接quorum /one / all,默认为quorum,即只有当大多数分片可用时才允许写操作。即使大多数可用,也可能存在因为网络等原因导致写入副本失败,这样该副本被认为故障,分片将会在一个不同的节点上重建。
3.对于读操作,可以设置replication和sync这使得操作在主分片和副本分片都完成后才会返回;如果设置replication为sync时,也可以通过设置搜索请求参数_referrnce为primary来查询主分片,确保文档是最新版本。
9.是否了解字典树?
字典树又称为单词查找树,Trie树,是一种树形结构,是一种哈希树的变种。典型应用是用于统计,排序和保存大量的字符串,所以经常被搜索引擎用于文本词频统计。它的优点是:利用字符串的公共前缀来减少拆线呢时间,是最大限度地减少无谓的字符串比较,查询效率比哈希树高。
Trie的核心思想是用空间来换时间,利用字符串的公共前缀,来降低查询时间的开销以达到高效率的目的。它有三个基本性质:
1.根节点不包括字符,除根节点外每一个节点都只包含一个字符。
2.从根节点到某一节点,路径上经过的字符连接起来,为该节点对应的字符串。
3.每个节点的所有子节点包含的字符都不相同。
对于中文的字典树,每个节点的子节点用一个哈希表存储,这样就不用太浪费太大的空间,而且查询速度上可以保留哈希的复杂度O(1)。
10.集群,节点,索引,文档,类型基本概念
1.集群是一个或多个节点(服务器)的集合,它们共同保存您的整个数据,并提供跨所有节点的联合索引和搜索功能。群集由唯一名称标识,默认情况下,为“elasticsearch”.此名称很重要,因为如果节点设置为按名称加入集群,则该节点只能是集群的一部分。
2.节点是属于集群一部分的单个服务器。它存储数据并参与到群集索引和搜索功能。
3.索引就像关系数据库中的“数据库”。它有一个定义多种类型的映射。索引是逻辑名称空间,映射到一个或多个分片,并且可以有零个或多个副本分片。
4.文档类似于数据中的一行数据。不同之处在于索引中的每个文档可以具有不同的结构,但是对于通用字段应该具有相同的数据类型。
5.类型是索引的逻辑类别/分区,其语义完全取决于用户。
11.ES中的倒排索引是什么?
倒排索引是搜索引擎的核心。搜索引擎的主要目的是在查找发生搜索条件的文档时提供快速搜索。ES中的倒排索引其实就是lucene的倒排索引,区别于传统的正向索引,倒排索引会在存储数据的时候将关键词和数据进行关联,保存到倒排表中,然后查询,将查询内容进行分分词后在倒排表中进行查询,最后匹配数据即可。