Elasticsearch核心原理与面试总结

这是一个关于 Elasticsearch 核心原理与常见面试问题的全面总结。内容分为两大部分:核心原理剖析常见面试问题与解答


Part 1:Elasticsearch 核心原理剖析

要真正掌握 Elasticsearch,必须理解其内部的几个核心设计思想。

1. 核心概念与架构
  • 集群、节点、分片、副本

    • 集群: 一个或多个节点的集合,共同持有全部数据,提供联合索引和搜索能力。

    • 节点: 一个运行中的 ES 实例,是集群的一部分。节点有多种角色(主节点、数据节点、协调节点、摄取节点等)。

    • 索引 : 一类文档的集合(类似关系型数据库中的 Database)。

    • 分片 : 索引可以被分成多个部分,每个部分就是一个分片。分片是 ES 实现水平扩展和分布式搜索的基石。索引创建时指定分片数,后续不可更改(除非重建索引)。

      • 主分片: 数据的原始分片。

      • 副本分片 : 主分片的拷贝,提供高可用性 (主分片挂掉,副本可提升为主)和提升读性能(搜索可以在所有副本上并行执行)。

  • 文档 & 映射

    • 文档 : ES 中的基本数据单元,是一个 JSON 对象(类似关系型数据库中的 Row)。

    • 映射 : 定义索引中文档的字段及其类型、分词器等(类似关系型数据库中的 Schema )。keyword 类型用于精确匹配(如排序、聚合、Term查询),text 类型用于全文检索(会被分词)。

2. 倒排索引

这是 ES 实现高速全文检索的根本数据结构。

  • 正排索引: 像一本书的目录,通过标题(文档ID)找到内容。

  • 倒排索引: 像一本书末尾的索引,通过关键词找到出现在哪些页码(文档ID)。

  • 组成

    • Term Dictionary: 对所有文档进行分词后得到的所有不重复的单词(Term)的集合。

    • Posting List: 对于每个 Term,记录包含它的所有文档的 ID 列表,以及在该文档中出现的位置、频率等信息。

举例

文档1:I love elasticsearch

文档2:I love coding

单词 文档ID
I [1, 2]
love [1, 2]
elasticsearch [1]
coding [2]

当搜索 love 时,直接查找倒排索引,立即得到文档 [1, 2]

优化 :Term Dictionary 很大,无法全部装入内存。ES 使用 FSTSkip List 等技术进行压缩和快速查找。

3. 写入流程 (Write Process)
  1. 协调节点: 客户端请求发送到任意节点,该节点成为协调节点。

  2. 路由计算 : 协调节点根据文档 _id 和路由规则(默认是 _id)计算文档应该存储在哪个主分片上:shard = hash(_routing) % number_of_primary_shards

  3. 转发请求 : 协调节点将写入请求转发到该主分片所在的主数据节点

  4. 写入主分片: 主数据节点执行以下操作:

    • 生成 _id(如果未提供)。

    • 验证映射和字段。

    • 将数据写入 Translog (事务日志,用于崩溃恢复)和 Memory Buffer(内存缓冲区)。

    • 此时数据还不可被搜索

  5. 返回响应: 主分片写入成功后,协调节点返回结果给客户端(可配置为等待不同级别的确认)。

  6. Refresh : 默认每 1 秒,Memory Buffer 中的数据会被写入到一个新的 Segment 文件中(在文件系统缓存中,未刷盘),并清空 Buffer。这个过程叫做 Refresh 。Refresh 后,新写入的文档才可以被搜索到。因此 ES 是 近实时 的。

  7. Flush : 默认每 30 分钟,或 Translog 达到一定大小时,会执行一次 Flush

    • 将文件系统缓存中的所有 Segment 刷到磁盘。

    • 清空 Translog,创建一个新的提交点。

4. 搜索流程 (Search Process)
  1. 查询阶段

    • 分发: 协调节点将搜索请求广播到索引的所有分片(主分片或副本分片)。

    • 执行: 每个分片在本地执行查询(使用倒排索引),得到一个本地优先级队列(包含排序后的前 N 个文档 ID 和分数)。

    • 返回: 每个分片将各自的队列结果返回给协调节点。

  2. 取回阶段

    • 合并排序: 协调节点合并所有分片的结果,进行全局排序,得到最终正确的 Top N 文档 ID 列表。

    • 取回文档 : 协调节点根据文档 ID,向相关分片发送 GET 请求,获取文档的原始数据。

    • 返回结果: 协调节点将完整的搜索结果返回给客户端。

5. 段合并

由于频繁的 Refresh 会产生大量小的 Segment 文件,搜索时需要遍历所有 Segment,效率低下。

ES 会在后台定期将多个小的、未删除的 Segment 合并成一个更大的 Segment,并物理删除标记为删除的文档。这个过程是 I/O 和 CPU 密集型的,但对提升搜索性能至关重要。


Part 2:常见面试问题与解答

基础概念类
  1. Elasticsearch 是什么?主要应用场景?

    • : 一个基于 Lucene 构建的分布式、RESTful 的开源搜索和分析引擎。核心场景:全文检索日志处理与分析 (ELK Stack)、实时数据分析应用性能监控
  2. Elasticsearch 和 MySQL 的区别?

    特性 Elasticsearch MySQL
    目的 搜索、分析、日志 事务、关系型数据存储
    数据结构 无 Schema(灵活,但有映射) 严格 Schema
    查询语言 JSON DSL SQL
    事务 不支持 ACID 支持 ACID
    扩展性 天生的分布式,易水平扩展 垂直扩展或分库分表较复杂
  3. 解释一下倒排索引,为什么它快?

    • : 如上文原理所述。它快是因为:1) 直接通过关键词定位文档,避免了全表扫描;2) 数据结构经过高度优化(FST压缩、跳表等);3) 可以高效地进行布尔运算(AND/OR/NOT)。
  4. Text 和 Keyword 类型的区别?

      • Text: 用于全文搜索。会被分词器拆分成多个词项,然后建立倒排索引。不用于排序和聚合

      • Keyword: 用于精确值匹配。整个字符串作为一个完整的词项存入索引。常用于过滤、排序、聚合

集群与分布式类
  1. 如何设计分片数和副本数?

    • : 这是一个权衡问题。

      • 主分片数 : 一旦设置,不可修改。建议:

        • 单个分片大小建议在 10GB - 50GB 之间。

        • 考虑数据增长,预留一定空间。

        • 分片过多会导致集群管理开销增大;过少则无法充分利用节点资源。

      • 副本数: 可以随时动态调整。

        • 至少设置为 1,以保证高可用。

        • 读多写少的场景可以增加副本数(如从 1 改为 2)来提升搜索吞吐量。

        • 副本数越多,写入性能会有一定下降(因为需要同步到更多副本)。

  2. 描述一下 Elasticsearch 的写入流程?为什么是近实时的?

    • : 参考上文核心原理。近实时 的原因在于数据从写入到可被搜索,中间有一个默认 1秒 的 Refresh 间隔。数据首先进入内存缓冲区,只有经过 Refresh 生成 Segment 后才能在搜索时被访问到。
  3. 描述一下 Elasticsearch 的搜索流程?

    • : 参考上文的"查询阶段"和"取回阶段"。
  4. Master 节点、Data 节点、Coordinating 节点的作用和区别?

      • 主节点 : 负责集群层面的轻量级操作,如创建/删除索引、跟踪节点状态、决定分片分配。不处理用户请求,数据压力小 。生产环境应配置专用主节点node.master: true, node.data: false)。

      • 数据节点 : 存储数据,执行数据的增、删、改、查和聚合操作。CPU、内存、I/O 密集型node.master: false, node.data: true)。

      • 协调节点 : 所有节点默认都是协调节点。负责接收客户端请求,将请求路由到正确的分片,并聚合结果。在大集群中,可以设置专用协调节点node.master: false, node.data: false)来分担数据节点的压力。

性能与优化类
  1. 如何优化 Elasticsearch 的搜索性能?

      • 硬件: 使用 SSD;保证足够内存(让文件系统缓存缓存更多的 Segment)。

      • 映射设计 : 避免不必要的字段;合理使用 keywordtext

      • 查询优化 : 避免深度分页(使用 search_after);使用 Filter 上下文(可缓存);避免通配符前缀查询。

      • 索引设计 : 基于时间的数据使用滚动索引;合理设置分片大小和数量。

      • 冷热架构: 将新/热数据放在 SSD 节点,旧/冷数据移到 HDD 节点。

  2. 如何优化 Elasticsearch 的写入性能?

      • 使用批量请求

      • 增加 refresh_interval(如设置为 30s),减少 Refresh 次数。

      • 在批量导入大量数据时,可以暂时禁用副本"number_of_replicas": 0),导入完成后再恢复。

      • 使用自动生成的 _id。ES 为自定义 _id 需要一次额外的查找来确认其唯一性。

      • 确保硬件 I/O 性能。

  3. 什么是深分页?为什么有问题?如何解决?

    • from 10000, size 10 这类查询就是深分页。问题在于协调节点需要从每个分片获取 10000+10 条数据,然后在内存中合并排序,最后再取第 10000 到 10010 条。开销极大,容易导致 OOM。

    • 解决方案

      • 避免: redesign 产品需求,如改为无限滚动。

      • search_after: 使用上一页的结果来帮助检索下一页,性能极好。

      • Scroll API: 用于离线导出大量数据,非实时。

  4. 你如何监控 Elasticsearch 集群的健康状态?

      • API_cluster/health(查看状态 green/yellow/red)、_nodes/stats(节点资源使用情况)、_cat API(简洁的概览信息)。

      • 监控指标: 集群状态、分片数、节点数、CPU/内存/磁盘使用率、索引/搜索速率和延迟、GC 情况。

      • 工具: Kibana Monitoring、Prometheus + Grafana、Cerbero、ElasticHQ。

希望这份详细的总结能帮助你深入理解 Elasticsearch 并为面试做好充分准备!

相关推荐
77qqqiqi4 小时前
安装es和kibana
elasticsearch·kibana
TDengine (老段)4 小时前
TDengine 时间函数 WEEKDAY() 用户手册
大数据·数据库·物联网·时序数据库·iot·tdengine·涛思数据
LQ深蹲不写BUG7 小时前
ElasticSearch 基础内容深度解析
大数据·elasticsearch·搜索引擎
2501_920047037 小时前
git在Linux中的使用
linux·git·elasticsearch
蒹葭玉树9 小时前
【C++上岸】C++常见面试题目--算法篇(第二十期)
c++·算法·面试
Debug_Snail9 小时前
【营销策略算法】关联规则学习-购物篮分析
大数据·人工智能
BYSJMG10 小时前
计算机毕设大数据方向:基于Spark+Hadoop的餐饮外卖平台数据分析系统【源码+文档+调试】
大数据·hadoop·分布式·python·spark·django·课程设计
java水泥工11 小时前
基于Echarts+HTML5可视化数据大屏展示-茶叶种植大数据溯源平台
大数据·echarts·html5