zoukankan      html  css  js  c++  java
  • ElasticSearch面试题

    1.索引调优

    设计阶段调优:

    1)根据业务增量需求,采取基于日期模板创建索引,通过rollover API滚动索引;见 ElasticSearch-rollover
    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)设置合理的路由机制。

    2.倒排索引

    见:ElasticSearch-倒排索引

    3.索引数据多了如何调优

    动态索引层面:

    基于 模板+时间+rollover api滚动创建索引,举例:设计阶段定义:blog索引的模板格式为:blog_index_时间戳的形式,每天递增数据。这样做的好处:不至于数据量激增导致单个索引数据量非常大,接近于上线2的32次幂-1,索引存储达到了TB+甚至更大。
    一旦单个索引很大,存储等各种风险也随之而来,所以要提前考虑+及早避免。

    存储层面:

    冷热数据分离存储,热数据(比如最近3天或者一周的数据),其余为冷数据。对于冷数据不会再写入新数据,可以考虑定期force_merge加shrink压缩操作,节省存储空间和检索效率。

    部署层面:

    一旦之前没有规划,这里就属于应急策略。结合ES自身的支持动态扩展的特点,动态新增机器的方式可以缓解集群压力,注意:如果之前主节点等 规划合理,不需要重启集群也能完成动态新增的。

    4.master选举实现

    前置条件:
    1)只有是候选主节点(master:true)的节点才能成为主节点。
    2)最小主节点数(min_master_nodes)的目的是防止脑裂。
    
    Elasticsearch 的选主是 ZenDiscovery 模块负责的,主要包含 Ping(节点之间通过这个RPC来发现彼此)和 Unicast(单播模块包含一个主机列表以控制哪些节点需要 ping 通)这两部分;
    获取主节点的核心入口为 findMaster,选择主节点成功返回对应 Master,否则返回 null。
    
    选举流程大致描述如下:
    第一步:确认候选主节点数达标,elasticsearch.yml 设置的值 discovery.zen.minimum_master_nodes;
    第二步:对所有候选主节点根据nodeId字典排序,每次选举每个节点都把自己所知道节点排一次序,然后选出第一个(第0位)节点,暂且认为它是master节点。
    第三步:如果对某个节点的投票数达到一定的值(候选主节点数n/2+1)并且该节点自己也选举自己,那这个节点就是master。否则重新选举一直到满足上述条件。

    5.文档搜索的过程

    ElasticSearch-集群 的分布式原理

    6.索引(写入)文档的过程

    ElasticSearch-集群 的数据写入过程

    7.更新和删除文档的过程

    删除和更新也都是写操作,但是 Elasticsearch 中的文档是不可变的,因此不能被删除或者改动以展示其变更。
    磁盘上的每个段都有一个相应的 .del 文件。当删除请求发送后,文档并没有真的被删除,而是在 .del 文件中被标记为删除。该文档依然能匹配查询,但是会在结果中被过滤掉。当段合并时,在 .del 文件中被标记为删除的文档将不会被写入新段。
    在新的文档被创建时,Elasticsearch 会为该文档指定一个版本号,当执行更新时,旧版本的文档在 .del 文件中被标记为删除,新版本的文档被索引到一个新段。旧版本的文档依然能匹配查询,但是会在结果中被过滤掉。

    8.如何解决集群脑裂问题

    所谓集群脑裂,是指 Elasticsearch 集群中的节点(比如共 20 个),其中的 10 个选了一个 master,另外 10 个选了另一个 master 的情况。
    当集群 master 候选数量不小于 3 个时,可以通过设置最少投票通过数量(discovery.zen.minimum_master_nodes)超过所有候选节点一半以上来解决脑裂问题;
    当候选数量为两个时,只能修改为唯一的一个 master 候选,其他作为 data 节点,避免脑裂问题。

    9.并发情况下,ES如果保证读写一致

    可以通过版本号使用乐观并发控制,以确保新版本不会被旧版本覆盖,由应用层来处理具体的冲突;
    另外对于写操作,一致性级别支持quorum/one/all,默认为quorum,即只有当大多数分片可用时才允许写操作。但即使大多数可用,也可能存在因为网络等原因导致写入副本失败,这样该副本被认为故障,分片将会在一个不同的节点上重建。
    对于读操作,可以设置replication为sync(默认),这使得操作在主分片和副本分片都完成后才会返回;如果设置replication为async时,也可以通过设置搜索请求参数_preference为primary来查询主分片,确保文档是最新版本。

    10.大数据量(上亿量级)的聚合如何实现

    Elasticsearch 提供的首个近似聚合是cardinality 度量。它提供一个字段的基数,即该字段的distinct或者unique值的数目。它是基于HLL算法的。
    HLL 会先对我们的输入作哈希运算,然后根据哈希运算的结果中的 bits 做概率估算从而得到基数。
    其特点是:可配置的精度,用来控制内存的使用(更精确 = 更多内存);小的数据集精度是非常高的;我们可以通过配置参数,来设置去重需要的固定内存使用量。无论数千还是数十亿的唯一值,内存使用量只与你配置的精确度相关。

     11.对于GC方面,在使用ES时要注意什么

    1)倒排词典的索引需要常驻内存,无法GC,需要监控data node上segment memory增长趋势。
    2)各类缓存,field cache, filter cache, indexing cache, bulk queue等等,要设置合理的大小,并且要应该根据最坏的情况来看heap是否够用,也就是各类缓存全部占满的时候,还有heap空间可以分配给其他任务吗?避免采用clear cache等“自欺欺人”的方式来释放内存。
    3)避免返回大量结果集的搜索与聚合。确实需要大量拉取数据的场景,可以采用scan & scroll api来实现。
    4)cluster stats驻留内存并无法水平扩展,超大规模集群可以考虑分拆成多个集群通过tribe node连接。
    5)想知道heap够不够,必须结合实际应用场景,并对集群的heap使用情况做持续的监控。

    12.数据类型

     见 ElasticSearch-数据类型

    13.分词器原理

    见 ElasticSearch-IK分词器 

    14.部署时,对Linux的设置有哪些优化方法

    1)关闭缓存swap;
    2)堆内存设置为:Min(节点内存/2, 32GB);
    3)设置最大文件句柄数;
    4)线程池+队列大小根据业务需要做调整;
    5)磁盘存储raid方式——存储有条件使用RAID10,增加单节点性能以及避免单节点存储故障。
  • 相关阅读:
    高精度计算
    高精度除以低精度
    P1258 小车问题
    POJ 2352 stars (树状数组入门经典!!!)
    HDU 3635 Dragon Balls(超级经典的带权并查集!!!新手入门)
    HDU 3938 Portal (离线并查集,此题思路很强!!!,得到所谓的距离很巧妙)
    POJ 1703 Find them, Catch them(确定元素归属集合的并查集)
    HDU Virtual Friends(超级经典的带权并查集)
    HDU 3047 Zjnu Stadium(带权并查集,难想到)
    HDU 3038 How Many Answers Are Wrong(带权并查集,真的很难想到是个并查集!!!)
  • 原文地址:https://www.cnblogs.com/ryjJava/p/14303666.html
Copyright © 2011-2022 走看看