ElasticSearch面试题
说一说你们公司ES的集群架构、数据规模以及调优手段
比如:ES集群架构13个节点,索引根据业务不同共20+索引,根据日期,每日递增20+,索引:10分片,每日递增1亿+数据,
每个业务每天索引大小控制:500GB之内。
设计阶段调优
1)根据业务增量需求,采取基于日期模板创建索引,通过roll over API滚动索引;
2)使用别名进行索引管理;
3)每天凌晨定时对索引做force_merge操作,以释放空间;
4)采取冷热分离机制,热数据存储到SSD,提高检索效率;冷数据定期进行shrink操作,以缩减存储;
5)采取索引生命周期管理;
6)仅针对需要分词的字段,合理的设置分词器;
7)Mapping阶段充分结合各个字段的属性,是否需要检索、是否需要存储等;
写入调优
1)写入前副本数设置为0;
2)写入前关闭refrESh_interval设置为-1,禁用刷新机制;
3)写入过程中:采取bulk批量写入;
4)写入后恢复副本数和刷新间隔;
5)尽量使用自动生成的id,避免指定id。
查询调优
1)禁用wildcard;
2)禁用批量terms(成百上千的场景);
3)充分利用倒排索引机制,能keyword类型尽量keyword;
4)数据量大时候,可以先基于时间敲定索引再检索;
5)设置合理的路由机制。
简述一下ES中的索引、类型、映射、文档各是什么?
索引(Index)
类似关系数据库中的“数据库”。它有一个定义多种类型的映射。索引是逻辑名称空间,映射到一个或多个主分片,并且可以有零个或多个副本分片。
类型(Type)
类似于数据库中的“表”,类型是索引内部的逻辑分区。因此,一个索引内部可定义一个或多个类型(type),一般来说,类型就是为那些拥有相同的域的文档做的预定义。
映射(Mapping)
类似于数据库中的“字段”,映射是定义文档及其包含的字段如何存储和索引的过程。
文档(Doc)
类似于关系数据库中的一行。不同之处在于索引中的每个文档可以具有不同的映射,但是对于通用字段应该具有相同的数据类型。
ES是如何实现Master选举的?
(1)ES的选主是ZenDiscovery模块负责的,主要包含Ping(节点之间通过这个RPC来发现彼此)和Unicast(单播模块包含一个主机列表以控制哪些节点需要ping通)这两部分;
(2)对所有可以成为master的节点(node.master: true)根据nodeId字典排序,每次选举每个节点都把自己所知道节点排一次序,然后选出第一个(第0位)节点,暂且认为它是master节点。
(3)如果对某个节点的投票数达到一定的值(可以成为master节点数n/2+1)并且该节点自己也选举自己,那这个节点就是master。否则重新选举一直到满足上述条件。
如何解决ES脑裂问题?
(1)当集群master候选数量不小于3个时,可以通过设置最少投票通过数量(discovery.zen.minimum_master_nodES)超过所有候选节点一半以上来解决脑裂问题;
(2)当候选数量为两个时,只能修改为唯一的一个master候选,其他作为data节点,避免脑裂问题。
简述Translog的作用
translog是用来恢复数据的。ES用“后写”的套路来加快写入速度,写入的索引并没有实时落盘到索引文件,而是先双写到内存和translog文件。
简述一下对ES分片的理解
(1)分片是指索引的分片,ES可以把一个完整的索引分成多个分片,这样的好处是可以把一个索引拆分成多个,分布到不同的节点上,从而构成分布式搜索。
(2)ES的分片分为主分片和副本分片:
主分片(Primary Shard),解决数据水平扩展的问题,通过主分片,将数据分布到集群内的所有节点上面。主分片数在索引创建的时候指定,之后不可以更改,除非重新索引。
副本分片(Replica Shard),解决数据的高可用问题,是主分片的拷贝。
ES中的副本分片可以用于读请求吗?
ES中的副本概念和Hadoop的副本类似,同样可以服务于读请求。
ES中的副本分片的作用有哪些?
故障转移/集群恢复
如果持有主分片的节点挂了,一个副本分片就会晋升为主分片。在索引写入时,副本分片做着与主分片相同的工作。新文档首先被索引进主分片然后再同步到其它所有的副本分片。
通过副本进行负载均衡
搜索性能取决于最慢的节点的响应时间,所以尝试均衡所有节点的负载是一个好想法。如果我们有三个节点,其中一个索引是两个主分片,每个主分片各有一个副本,那么一共就是4块分片,最终我们会有两个节点各持有一个分片,而另一个持有两个分片做着两倍的工作。我们可以通过调整副本数量来平衡这些分片,通过分配两份副本而不是一个,最终我们会拥有六个分片,刚好可以平均分给三个节点。
描述一下ES更新和删除文档的过程
删除和更新都是写操作,但是ES中的文档是不可变的,因此不能被删除或者改动以展示其变更,具体过程如下:
删除过程
磁盘上的每个段都有一个相应的.del文件。当删除请求发送后,文档并没有真的被删除,而是在.del文件中被标记为删除。该文档依然能匹配查询,但是会在结果中被过滤掉。当段合并时,在.del文件中被标记为删除的文档将不会被写入新段。
更新过程
在新的文档被创建时,ES会为该文档指定一个版本号,当执行更新时,旧版本的文档在.del文件中被标记为删除,新版本的文档被索引到一个新段。旧版本的文档依然能匹配查询,但是会在结果中被过滤掉。
简述一下ES的倒排索引是什么
传统检索是通过文章,逐个遍历找到对应关键词的位置。而倒排索引,是通过分词策略,形成了词和文章的映射关系表,这种词典+映射表即为倒排索引。有了倒排索引可以极大的提高了检索效率。
ES查询队列满,请求拒绝,简述一下解决思路
队列大小一般不需要调整,队列满的原因是请求处理不过来,调大之后解决不了根本问题。
(1)首先看看分片在节点上的分布是否均匀,分布得不均匀容易出现队列打满的情况,可以通过重新规划分片,更加充分地利用节点的资源;
(2)如果分片均衡没有问题,可以把慢日志打开,查看是否有大量查询比较慢的请求,如果有的话,需要联系业务侧分析该类请求;
(3)如果以上两点做了之后,队列还是会满,那说明节点资源不足以支撑请求量,需要考虑扩容。
我的博客即将同步至腾讯云+社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=2g8usghg53wgg