面试题篇-15-Es相关面试题

1. 如何在执行模糊搜索(Fuzzy Search)?

在Elasticsearch中,可以使用模糊搜索(Fuzzy Search)来查找与给定术语相似的文档。模糊搜索是一种基于编辑距离的近似匹配方法,可以处理拼写错误或相似词的情况。

2. 倒排索引

倒排索引是一种数据结构,用于加速文本搜索。它将每个文档中的每个词映射到包含该词的文档列表中。

在商业项目中,例如新闻发布平台,Elasticsearch的倒排索引可以将每个关键词映射到包含该关键词的新闻文章列表中,以实现快速的关键词搜索。

3. 聚合操作

如何在Elasticsearch中执行复杂的聚合操作?

在Elasticsearch中,可以使用聚合操作对数据进行统计和分析。

例如,在一个社交媒体平台的商业项目中,可以使用Elasticsearch的聚合功能来进行用户行为分析。通过聚合操作,可以计算用户的活跃度、点赞和评论数量、用户关注的话题等。这些统计数据可以帮助平台了解用户行为模式,优化推荐算法和个性化内容展示。

4. 数据冗余和高可用

在商业项目中,例如在线电商平台,可以使用Elasticsearch的数据冗余和高可用性机制来确保订单数据的安全和可靠。

通过配置适当数量的副本,可以实现数据的冗余存储和高可用性。当主分片不可用时,副本可以接管服务,确保订单数据的持续访问和处理。

5. 性能优化

  • 硬件优化:配置适当的硬件资源,如增加内存、优化磁盘I/O性能等,以提高Elasticsearch的整体性能。
  • 分片和副本优化:根据数据量和查询负载的需求,调整分片和副本的数量和分布,以平衡数据分布和查询负载。
  • 索引和映射优化:设计合理的索引和映射,选择合适的字段类型、分析器和分词器,以提高搜索和聚合的性能。
  • 查询和过滤器优化:使用合适的查询和过滤器,避免全文搜索和聚合操作的过度使用,以提高查询性能。
  • 缓存和预热优化:使用缓存机制,如Elasticsearch的请求缓存或外部缓存,缓存频繁查询的结果,以减少重复计算的开销。预热机制可以在系统启动时加载常用数据,提前准备好热门查询的结果。
  • 索引生命周期管理:根据数据的使用情况,定期删除过期的数据和索引,以减少存储和查询负载。
  • 监控和调优:使用Elasticsearch的监控工具和指标,监控集群的健康状态、节点的负载、响应时间和资源利用率等

6. 查询和写入优化

6.1 设计阶段调优

  • ES数据区分热、温、冷三个阶段
  • ES索引按月滚动生成
  • mapping设置合理的数据类型是否需要分词
  • 使用别名管理索引

6.2 数据写入优化

  • 单条写入改为多条数据写入

  • 自动生成ID

  • 索引刷盘时间,index.refresh_interval: 30s; 默认1s改为30s,减少刷盘频次

  • 大批量数据导入时,可以把副本分片设置为0

  • 设置segment段大小,参数如下:
    indices.memory.index_buffer_size: 20% (最大堆内存百分比)
    indices.memory.min_index_buffer_size: 96mb (最小缓存大小)

  • 设置节点之间的故障检测配置,例如以下elasticsearch.yml配置:
    discovery.zen.fd.ping_timeout: 120s
    discovery.zen.fd.ping_retries: 6
    discovery.zen.fd.ping_interval: 30s

6.3 查询优化

6.3.1 分片数合理评估

  • 集群总分片数建议控制在5w以内,单个索引的规模控制在 1TB 以内,单个分片大小控制在30 ~ 50GB ,docs数控制在10亿内,如果超过建议滚动;(预估就就是分片数最好小于20)
  • 分片的数量通常建议小于或等于ES 的数据节点数量,最大不超过总节点数的2倍,通过增加分片数可以提升并发;
  • 分片数越多长尾效应越明显,并不是越多越好,在搜索场景合理控制分片数也可以提升性能。

6.3.2 mapping设计

  • 合理设置 index:false(是否可索引),store:false(是否存储),doc_values:false (是否倒排)
  • 长字段增加序列化和高亮开销,但字段长度不能高于65536(short?),超长配置: ignore_above 忽略超长的数据。
  • 合理设置keyword类型,使用倒排索引。
  • 合理使用fields属性,对于text字段设置子字段为keyword,支持text和keyword两种功能。

7. es和mysql查询性能对比

  • es天生的分布式架构,天然支持海量数据的分片和查询,而mysql不是分布式架构;

  • mysql和es底层索引结构导致即便是单片数据查询,es也更适合做查询引擎;

具体分析过程如下:

7.1 为什么mysql做不了海量数据的实时查询?

mysql的架构就不是分布式的架构,就算基于一些开源组件或者自研组件做了分库分表,也只能解决数据的存储问题,解决不了问题的查询问题。目前所有的分库分表中间件都会要求必须带上分库分表id去查询,也就是分库分表之后,你的查询,最终还是要落到某个库某张表去做单库单表的实时查询。

7.2 而ES为啥能够做海量数据的实时查询?

ES天生就是分布式架构,假如有一个学生表超过10亿条数据,导入es。首先第一件事情就是你要给这些数据做分片,假如分了10片后,用户想基于name去查询,es是怎么做的?这里我们假设是最简单的部署架构,es的节点A接收到查询请求后,会把请求转发到其他datanode,然后每个datanode接收到数据后,会在本机进行数据查询,然后将查询结果id,score返回节点A,然后由节点A对所有返回结果再进行排序和分页,然后节点A再去各个datanode,依据id拿到原始数据合并后返回给用户。

7.3 为什么mysql不这样做呢?

个人理解,不是mysql或者分库分表中间件不想做,而是根本做不了。原因是单库单表mysql也支持不了复杂查询条件下的实时查询,比如任意列的相互组合查询。

想要快速查询,避免全表扫描,就需要索引。mysql可以对单列增加索引,也可以对多列增加索引,或者按照一定顺序建立多个字段的组合索引。但mysql的索引存在很多问题:

  • mysql单列索引的问题是通常用户查询条件不会仅仅只有一个。

  • mysql多列索引问题是mysql引擎执行是只会选择最严格那一个索引执行,然后在其“中间结果集”上进行其他条件的过滤(后面可以看到es不是这样做的)。这意味着建多列索引实际上可能是无用的。

  • mysql组合索引的问题是建立组合索引,是要按照顺序的,而且执行的时候是从左到右匹配执行的,一旦查询条件不符合索引组合次序,或者查询条件多变,组合索引就会毫无用处。

es的底层是lucene,lucene的索引叫倒排索引(Inverted Index)。
下面是一个倒排索引的示例图:
在这里插入图片描述

倒排索引(Inverted Index):倒排索引是实现“单词-文档矩阵”的一种具体存储形式,通过倒排索引,可以根据单词快速获取包含这个单词的文档列表。比如上图中,lucene这个单词对应的documentId list就是2,3,10,35,92;

倒排索引主要由两个部分组成:“单词词典”和“倒排列表”。

  • 单词词典(Lexicon):搜索引擎的通常索引单位是单词,单词词典是由文档集合中出现过的所有单词构成的字符串集合,单词词典内每条索引项记载单词本身的一些信息以及指向“倒排列表”的指针。
  • 倒排列表(PostingList):倒排列表记载了出现过某个单词的所有文档的文档列表及单词在该文档中出现的位置信息,每条记录称为一个倒排项(Posting)。根据倒排列表,即可获知哪些文档包含某个单词。
  • 倒排文件(Inverted File):所有单词的倒排列表往往顺序地存储在磁盘的某个文件里,这个文件即被称之为倒排文件。
  • 在这里插入图片描述

8. Es的副本和分片怎么理解

几个概念名词:

  • 集群(cluster)
    由一个或多个节点组成, 并通过集群名称与其他集群进行区分,通常有一个master节点;
    一个正常es集群中只有一个主节点(Master),主节点负责管理整个集群;
  • 节点(node)
    单个ElasticSearch实例. 通常一个节点运行在一个隔离的容器或虚拟机中;
  • 索引(index)
    在ES中, 索引是一组文档的集合
  • 分片(shard)
    因为ES是个分布式的搜索引擎, 所以索引通常都会分解成不同部分, 而这些分布在不同节点的数据就是分片
    ES自动管理和组织分片, 并在必要的时候对分片数据进行再平衡分配, 所以用户基本上不用担心分片的处理细节
    一个分片默认最大文档数量是20亿
    Elasticsearch集群允许系统存储的数据量超过单机容量,这是通过shard实现的。
    在一个索引index中,数据(document)被分片处理(sharding)到多个分片上。
    也就是说:每个分片都保存了全部数据中的一部分。
    一个分片是一个 Lucene 的实例,它本身就是一个完整的搜索引擎。
    文档被存储到分片内,但应用程序直接与索引而不是与分片进行交互。
  • 副本(replica)
    ES默认为一个索引创建5个主分片, 并分别为其创建一个副本分片. 也就是说每个索引都由5个主分片成本, 而每个主分片都相应的有一个copy. 这个就是副本;
    主分片与副本都能处理查询请求, 它们的唯一区别在于 只有主分片才能处理索引请求.
    副本的作用如下:
    • 提高系统容错性
      当分片所在的机器宕机时,Elasticsearch可以使用其副本进行恢复,从而避免数据丢失
    • 提高ES查询效率
      处理查询时,ES会把副本分片和主分片公平对待,将查询请求负载均衡到副本分片和主分片

如下图所示 , ElasticSearch集群有两个节点, 并使用了默认的分片配置. ES自动把这5个主分片分配到2个节点上, 而它们分别对应的副本则在完全不同的节点上. 对,就这是分布式的概念.
在这里插入图片描述

8.1 分片原理

8.1.1 分片内部原理

Elasticsearch数据存储在分片中,然后分片分配到集群中的节点上。当集群扩容或缩小,Elasticsearch 将会自动在节点间迁移分片,以使集群保持平衡,当集群中部分节点停止服务,整个集群不受影响。一个分片是一个最小的工作单元,它只是保存了索引中所有数据的一部分。
  默认情况下,一个索引被分配 5 个主分片(在Elasticsearch7中默认仅分配一个主分片),可以使用以下命令配置主分片和副本分片个数。

PUT /AAA
{
    "settings": {
        "number_of_shards": 3,
        "number_of_replicas": 1
    }
}

主分片的数量决定了索引最多能存储多少数据,主分片过小会在索引增长较快的时候,集群无法通过增加节点实现对这个索引的数据扩展;主分片数过大会导致单个shard容量很小,引发一个节点上过多分片,影响性能;

在一个多分片的索引中写入数据时,通过路由来确定具体写入哪一个分片中,大致路由过程如下:

shard = hash(routing) % number_of_primary_shards

routing 是一个可变值,默认是文档的 _id ,也可以设置成一个自定义的值。routing 通过 hash 函数生成一个数字,然后这个数字再除以 number_of_primary_shards (主分片的数量)后得到余数 。这个在 0 到 number_of_primary_shards 之间的余数,就是所寻求的文档所在分片的位置。
 如果主分片数量发生变化,那么所有之前路由的值都会无效,文档就无法被检索,所以Elasticsearch不支持扩展主分片,除非重建索引。

8.1.2 副本

副本分片是主分片的一个副本,可以防止硬件故障导致的数据丢失,同时可以提供读请求,副本分片设置过多,会降低集群整体写入性能。
  每个主分片应该至少有一个副本分片,当主分片异常时,副本可以promote为主节点。主分片和对应的副本分片是不会在同一个节点上的,所以副本分片数的最大值是 n -1(其中 n 为节点数)。
  当索引创建完成的时候,主分片的数量就固定了,但是副本分片的数量可以随时调整,根据需求扩大或者缩小规模。

PUT /AAA/_settings 
{
    "number_of_replicas": 2
}

主分片或者副本分片都可以处理读请求——搜索或文档检索,所以数据的冗余越多,能处理的搜索吞吐量就越大。

节点分类

  • Coordinating Node-路由请求
    路由请求,所有节点默认都是Coordinating Node,通过将其他类型设置成False,使其变成Coordinating Node节点。
  • Data Node-保存数据
    节点启动后,默认就是数据节点,可以设置成node.data: false 禁止。通过增加数据节点,可以解决数据水平扩展和解决数据单点的问题。
  • Master Node-处理请求
    处理创建、删除索引等请求、决定分片分到那个节点,维护并更新Cluster 状态。在每一个节点上都保存了集群的状态信息。但是,只有Master节点上才能修改集群状态的信息,并负责同步给其他节点。
  • 8
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Alan0517

感谢您的鼓励与支持!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值