Elasticsearch 高频面试题及详细答案
一、基础概念篇
1. 什么是 Elasticsearch?核心优势是什么?
Elasticsearch 是一款基于 Lucene 开发的分布式、可扩展、实时的全文搜索引擎与数据分析引擎,使用 Java 开发,支持 RESTful API 操作,是目前主流的日志检索、业务检索、大数据实时分析中间件。
核心优势:
分布式架构:天然支持集群部署,支持横向扩容、高可用
全文检索能力强:支持分词、模糊查询、高亮、权重排序
实时近实时:数据写入后 1 秒左右可被检索(NRT 近实时)
丰富的聚合分析:支持桶聚合、指标聚合,可快速做统计分析
无 schema 灵活:支持动态映射,适配多变业务数据
生态完善:搭配 Kibana、Logstash、Beat 形成 ELK 日志栈
2. ES、MySQL、Redis 的适用场景区别?
MySQL:结构化数据、事务、增删改查、强一致性、业务主数据存储,不适合海量模糊检索
Redis:热点数据缓存、分布式锁、计数器、限流,纯内存高速读写,不适合复杂全文检索
ES:海量数据全文检索、日志分析、实时统计、模糊匹配、分词检索,不适合强事务、高频更新场景
3. 什么是 NRT 近实时搜索?为什么 ES 不是实时?
ES 写入数据后不会立刻对检索可见,默认 1 秒刷新一次索引,这个特性就是近实时搜索。
原因:ES 为了提升写入性能,写入数据先写入内存缓冲区,不会立刻落地磁盘;只有执行refresh操作后,缓冲区数据生成段文件,才可以被检索。手动刷新可以设置 refresh=true,但会严重降低写入性能。
二、核心架构与名词解释
4. 讲解 ES 核心概念:索引、类型、文档、分片、副本
索引(Index):一类相似文档的集合,相当于 MySQL 的数据库/表,是数据存储的基本单元
文档(Document):ES 最小数据单元,JSON 格式,相当于 MySQL 一行数据
字段(Field):文档中的属性,相当于 MySQL 字段
主分片(Primary Shard):索引数据拆分的分片,负责读写、数据写入,主分片数量创建后不可修改
副本分片(Replica Shard):主分片的备份,负责读请求、故障容灾,副本数可以动态修改
核心规则:主分片和副本不会在同一台节点,保证节点宕机不丢数据。
5. 分片为什么不能修改?分片数量如何合理设计?
主分片基于哈希取模路由数据,公式:shard = hash(_id) % number_of_primary_shards。如果修改主分片数量,所有数据路由规则全部失效,数据彻底错乱,因此主分片数固定不可改。
分片设计原则:
单分片数据量建议控制在20G-50G最佳
分片数量不宜过多,过多会导致元数据压力大、查询变慢
副本数至少 1,保证高可用,生产环境不允许 0 副本
6. 什么是段(Segment)?段合并的作用和问题?
ES 底层基于 Lucene 段文件存储数据,每次 refresh 都会生成一个新的小段文件,段文件是只读的。
段合并:后台线程将多个小段合并为大段,删除已标记删除的数据,减少段文件数量,提升查询性能。
缺点:段合并会大量占用 CPU、IO、磁盘,高峰期容易导致集群压力飙升,引发查询卡顿。
三、索引与映射机制
7. 动态映射和静态映射区别?生产推荐哪种?
动态映射:自动根据写入 JSON 字段推断类型,无需提前建表,上手快,但容易出现类型错乱(数字变字符串、日期识别异常)
静态映射:手动定义字段类型、分词器、是否索引、是否存储,类型可控、性能稳定
生产强制推荐静态映射,避免动态映射导致的字段类型异常、检索失效问题。
8. text 和 keyword 区别?使用场景?
text:会分词,支持模糊检索、全文搜索,不支持聚合、排序(分词后多词条无法精准排序)
keyword:不分词,完整存储原文,支持精准查询、聚合、排序、分组统计
通用最佳实践:字符串字段设置text+keyword 双字段,搜索用 text,聚合排序用 keyword。
9. index、store 属性作用?
index=true:字段建立索引,可以被检索(默认开启)
index=false:不建立索引,无法搜索,节省索引空间
store=true:单独存储字段数据,默认 false,_source 已存储全量数据,无需重复存储
四、写入、更新、删除原理
10. ES 数据写入完整流程?
客户端请求到达 coordinating node(协调节点)
协调节点根据文档 _id 哈希路由,定位目标主分片节点
请求转发至主分片节点,主分片执行写入、校验数据
主分片同步数据到所有副本分片
全部写入成功后,返回响应给客户端
数据先写内存缓冲区 + translog 事务日志,定时 refresh、flush 落盘
11. ES 更新为什么是先删后写?
Lucene 段文件只读不可修改,因此 ES 无法原地更新数据。更新时:旧文档标记删除,写入一条新文档,段合并时彻底清理旧数据。
因此 ES不适合高频更新业务,频繁更新会产生大量删除标记、小段文件,严重影响性能。
12. translog 事务日志作用?
内存缓冲区数据未落地磁盘,宕机就会丢失。translog 实时记录写入操作,用于故障恢复。
flush 操作会将内存数据写入磁盘,清空 translog 日志,完成持久化。
五、检索与查询原理
13. match 和 term 查询区别?
term:精准匹配,不分词,直接匹配词条,适合 keyword、数字、日期
match:会对查询语句分词,再去索引匹配,适合 text 全文检索
常见坑:text 字段用 term 查不到数据,因为字段已分词,词条和原文本不一致。
14. 什么是倒排索引?原理是什么?
倒排索引是 ES 检索的核心,区别于正向索引(文档→词条),倒排索引是词条→文档的映射结构。
结构:词条字典 + 倒排记录表,记录词条出现的文档、频次、位置。
优势:海量数据下,根据关键词快速匹配文档,检索效率远高于数据库模糊查询。
15. bool 查询的四种逻辑?
must:必须匹配,参与算分
filter:必须匹配,不参与算分、可缓存,性能最高
should:可选匹配,满足任意一个,提升相关性得分
must_not:必须不匹配,不参与算分
优化原则:过滤条件全部放 filter,减少算分、利用缓存。
六、聚合分析
16. ES 常用聚合类型?
指标聚合(Metric):sum、avg、max、min、count、distinct_count 去重统计
桶聚合(Bucket):terms 分组、date_histogram 时间直方图、range 区间分组
聚合执行顺序:先分桶、后算指标。
17. terms 聚合精准度问题?如何解决?
分布式聚合会出现数据近似误差,每个分片独立统计,合并结果会有偏差,数据量大时 topN 不准。
解决方案:调高 size、shard_size 参数,牺牲性能换取精准度;极致精准使用 cardinality 或二次聚合。
七、性能优化(高频重点)
18. ES 写入优化方案?
批量写入:使用 bulk 接口,单次 1000-5000 条最佳
调大刷新间隔:index.refresh_interval 调至 3s-10s,减少刷新次数
关闭副本:大批量初始化数据时,临时设置副本数为 0,写入完成再恢复
合理分片:单分片控制 50G 以内
禁用动态映射,提前建好静态 mapping
19. ES 查询优化方案?
能 filter 不 must,减少算分、开启查询缓存
精准字段用 keyword,避免 text 分词查询
限制返回字段,使用 _source 过滤不需要字段
避免深分页(from+size 超大值),改用 scroll / search_after
合理设置分片,避免分片过多
20. 深分页问题?解决方案?
from+size 分页,深度越深,协调节点需要聚合所有分片大量数据、排序裁剪,内存和 CPU 消耗极高,会触发熔断报错。
解决方案:
常规海量分页:search_after(推荐,无状态、性能高)
一次性批量导出:scroll 查询
业务限制:禁止前端超大深度分页
八、集群与高可用
21. 集群节点角色?
主节点(Master):负责集群管理、分片分配、元数据更新,不负责数据读写
数据节点(Data):负责数据存储、读写、聚合计算
协调节点(Coordinate):接收请求、路由、结果合并,无数据存储
生产最佳实践:分离主节点、数据节点,避免主节点压力过大导致集群异常。
22. 脑裂问题是什么?如何解决?
网络波动导致集群分裂为两个子集群,各自选举主节点,数据分片错乱、集群数据不一致,即为脑裂。
解决方案:设置discovery.zen.minimum_master_nodes = (集群主节点数/2)+1,保证多数节点选举,避免脑裂。新版 ES 已自动适配。
九、常见故障与面试压轴题
23. 索引变红、变黄原因?
黄色(yellow):主分片正常,副本分片未分配(节点不足、磁盘不足、分片数超限)
红色(red):存在主分片未分配,数据无法读写,索引异常不可用
24. ES 磁盘爆满如何处理?
临时:清理过期索引、关闭分片自动分配、临时调高磁盘水位
根治:开启索引生命周期 ILM,自动删除过期日志索引;扩容磁盘;拆分大索引
25. 为什么不建议用 ES 做实时事务业务?
无事务机制,不支持 ACID
更新是删除+新增,高频更新性能差
近实时机制,数据写入不能立刻查询
分布式一致性弱,不适合金融、订单等强一致场景
