Elasticsearch 面试题
本页只放标准回答和追问点,详细原理、流程图、Demo 和商业训练回到知识点页学习。项目训练入口:Elasticsearch 商业场景训练营。
本页只放 Elasticsearch 面试标准回答、项目话术、常见追问和知识点跳转。底层原理、流程图、Demo、排查步骤统一放在知识点页。
使用方式
mermaid
flowchart TD
A["面试页:组织回答"] --> B["知识点页:理解原理"]
B --> C["项目场景:商品、订单、工单、日志、资产搜索"]基础定位
| 面试题 | 标准回答 | 原理知识点 |
|---|---|---|
| ES 怎么从零学到生产可用 | Elasticsearch 要按定位、文档模型、Mapping、倒排索引、分词、写入 refresh、Query/Fetch、集群分片、同步一致性和生产排查这条线学习。先明确 MySQL 是事实源,ES 是搜索视图;再按搜索页面设计文档和 Mapping。工程上要掌握 MQ/CDC 同步、幂等、乱序、失败重试、死信、补偿、别名重建,以及搜不到、搜不准、查询慢、写入慢和 red/yellow 的排查流程。学完后要能用验收清单证明自己能设计索引、解释原理、处理失败和排查线上问题。 | 从零到生产级掌握、从零到精通验收清单 |
| Elasticsearch 是什么 | ES 是基于 Lucene 的分布式搜索和分析引擎,擅长全文检索、相关性排序、高亮、聚合、日志检索和近实时查询。它通常作为搜索视图,不是交易主库。 | 总览、核心概念 |
| ES 和 Lucene 什么关系 | Lucene 是单机搜索引擎库,提供倒排索引、分词、评分、段文件等核心能力;ES 把 Lucene 封装成分布式服务,提供 REST API、分片、副本、集群管理和分布式查询。 | 底层原理 |
| ES 为什么不直接替代 MySQL | MySQL 适合事务、关系模型和强一致事实数据;ES 适合搜索、过滤、聚合和近实时分析。ES 更新成本高、Join 能力弱、搜索通常最终一致,所以订单、库存、支付仍以主库为准。 | 核心概念、底层原理 |
为什么不用数据库 like | like '%关键词%' 大数据量下很难利用普通索引,也没有中文分词、相关性排序、高亮、同义词、聚合筛选。ES 写入时提前分词并建立倒排索引,搜索时直接按词找候选文档。 | 倒排索引与 BM25 |
| ES 为什么查询快 | 核心是把搜索成本前置到写入阶段。写入时分词并建立倒排索引,查询时先通过 term dictionary 定位词,再读取 posting list 得到候选文档;硬条件用 filter/bitset 过滤,排序聚合走列式 doc values,多个分片并行查询后由协调节点合并 TopN。所以它不用逐行扫描文本。但深分页、大聚合、通配、脚本排序、分片过多仍然会慢。 | 查询快的完整底层链路、Query 与 Fetch |
| ES 为什么叫近实时搜索 | 写入成功后文档先进入内存 buffer 和 translog,等 refresh 生成可搜索 segment 后才能被搜索到。默认通常有短暂延迟,所以叫 Near Real-Time,而不是强实时。 | 写入、Refresh 与 Segment |
索引与 Mapping
| 面试题 | 标准回答 | 原理知识点 |
|---|---|---|
| 什么是倒排索引 | 倒排索引是“词到文档”的映射。写入时文本被分词,记录每个词出现在哪些文档里;查询时先找词对应的文档列表,再合并、评分和排序。 | 倒排索引与 BM25 |
| 倒排索引里保存什么 | 不只保存词和文档 ID,还可能保存词频、位置、偏移量、字段长度归一化等信息,用于相关性评分、短语查询和高亮。 | 倒排索引与 BM25 |
text 和 keyword 区别 | text 会分词,适合全文检索和高亮;keyword 不分词,适合精确过滤、排序和聚合。商品名常用 text 加 keyword 子字段。 | Mapping与查询 |
| Mapping 为什么重要 | Mapping 决定字段类型、是否分词、能否排序聚合、使用什么 analyzer。字段类型设计错了,查询语句再复杂也可能搜不到或聚合报错。 | Mapping与查询 |
| Mapping 改错为什么通常要重建索引 | 已有字段已经按旧类型和旧 analyzer 建了底层索引结构,通常不能直接改字段类型或让历史数据自动重分词。标准做法是新建索引、全量导入、增量同步、别名切换。 | 同步与重建索引 |
| dynamic mapping 有什么风险 | ES 自动推断字段类型可能推错,例如第一次写入价格是字符串,后续范围查询和排序就会麻烦。生产建议显式 Mapping,关键索引用 dynamic: strict 控制字段。 | Mapping与查询 |
| doc values 是什么 | doc values 是面向列的字段存储,适合排序、聚合和脚本读取;倒排索引是 term 到 docs,适合搜索和过滤。聚合排序字段通常要用 keyword、数值、日期。 | doc values |
分词与查询
| 面试题 | 标准回答 | 原理知识点 |
|---|---|---|
| 分词器做什么 | 分词器把文本拆成 token,并做大小写、停用词、同义词等处理。中文、品牌、型号、中英文混合搜索很依赖分词质量。 | 倒排索引与 BM25、分词 |
| 索引分词和查询分词区别 | 索引分词发生在写入时,决定倒排索引里有什么词;查询分词发生在搜索时,决定拿哪些词去查倒排索引。两者不匹配会导致搜不到或召回差。 | 倒排索引与 BM25 |
term 和 match 区别 | term 不分析查询词,适合查 keyword、ID、状态;match 会分析查询词,适合查 text 全文字段。用 term 查 text 的整句话,经常搜不到。 | 倒排索引与 BM25 |
must 和 filter 区别 | must 参与相关性评分,适合关键词匹配;filter 不参与评分,适合品牌、类目、状态、权限、时间范围等硬条件,通常更容易缓存。 | Query 与 Fetch |
should 有什么用 | should 可用于扩展召回或加权,命中后提高分数;在有 must 或 filter 时默认不一定强制命中,可以用 minimum_should_match 控制。 | Mapping与查询 |
| bool 查询怎么设计 | 关键词放 must,状态、类目、价格、权限放 filter,运营加权、标签、销量段放 should。这样既能保证召回,也能控制评分和过滤性能。 | Mapping与查询 |
| wildcard 为什么慢 | 尤其是 *xxx 前缀通配很难利用高效的词典定位,可能扫描大量 term。搜索建议和模糊输入通常用分词、ngram、search_as_you_type 或专门建议索引。 | 性能优化与排查 |
写入、更新与近实时
| 面试题 | 标准回答 | 原理知识点 |
|---|---|---|
| ES 写入流程是什么 | 协调节点接收请求,根据 _id 或 routing 找到主分片;主分片写入内存 buffer 和 translog,再复制到副本,满足确认条件后返回。refresh 后新 segment 可搜索。 | 写入、Refresh 与 Segment |
| refresh、flush、merge 区别 | refresh 让新数据变成可搜索 segment;flush 做 Lucene commit 并清理 translog;merge 合并小 segment、清理删除标记、减少查询开销。 | 写入、Refresh 与 Segment |
| ES 更新为什么成本高 | Lucene segment 不可变,更新不是原地修改,而是旧文档打删除标记,再写入新文档,后续 merge 时清理旧数据。高频更新会带来写入和 merge 压力。 | 写入、Refresh 与 Segment |
| 写入成功但搜不到怎么办 | 先判断是否 refresh 未完成;如果超过预期,按 ID 查 ES 文档,再查同步日志、MQ/CDC 延迟、Mapping、分词和过滤条件。 | 性能优化与排查 |
| Bulk 为什么能提升写入 | Bulk 把多条写入合并成一次网络请求和批量处理,减少网络往返,提高吞吐。但批次不是越大越好,过大容易内存压力和失败重试成本高。 | Bulk |
分布式与集群
| 面试题 | 标准回答 | 原理知识点 |
|---|---|---|
| 分片和副本有什么用 | 主分片做数据水平拆分,提升容量和并行能力;副本提高查询吞吐和故障恢复能力。副本不会和自己的主分片放同一节点。 | 集群 |
| 分片越多越好吗 | 不是。分片太多会增加集群元数据、查询协调、内存、文件句柄、恢复迁移成本。分片数量要根据数据量、增长速度、节点数和查询模式规划。 | 集群:分片规划 |
| 查询请求在集群里怎么执行 | 协调节点接收请求,分发给相关分片;各分片本地查询 TopN,协调节点合并排序,再 fetch 需要的 _source 返回给客户端。 | Query 与 Fetch |
| yellow 和 red 区别 | yellow 表示主分片正常但部分副本未分配;red 表示部分主分片不可用。单节点开发环境有副本时 yellow 常见,生产 red 要优先处理。 | 集群 |
| 分片未分配怎么查 | 先看 _cluster/health、_cat/shards,再用 _cluster/allocation/explain 看具体原因,常见是节点不足、磁盘水位、分配规则或分片损坏。 | 性能优化与排查 |
| 磁盘水位有什么影响 | 磁盘超过水位后 ES 会限制分片分配,严重时索引会被设置为只读,导致写入失败。要清理过期索引、扩容、调整 ILM,水位下降后解除只读。 | 集群:磁盘水位 |
同步与重建
| 面试题 | 标准回答 | 原理知识点 |
|---|---|---|
| MySQL 数据怎么同步到 ES | 常见方式有同步双写、MQ 异步、Binlog CDC、本地消息表、RocketMQ 事务消息和定时补偿。商业项目常用 MQ 或 CDC 做主链路,补偿任务兜底,保证最终一致。 | MySQL 与 ES 一致性、同步与重建索引 |
| MySQL 和 ES 如何保证数据一致性 | 先明确 MySQL 是事实来源,ES 是搜索视图,不追求强一致。写主库成功后通过可靠事件同步 ES,消费端按 ID 查 MySQL 最新快照,写 ES 要幂等、防乱序,失败进入重试和死信,定时补偿和对账兜底,关键交易读 MySQL。 | MySQL 与 ES 一致性 |
| 同步双写有什么问题 | 业务写 MySQL 后再写 ES,实现简单但容易受 ES 抖动影响主流程;MySQL 成功、ES 失败会出现不一致,ES 超时还不知道是否写入成功。核心链路更推荐异步、幂等和补偿。 | 为什么同步双写不推荐 |
| MQ 同步为什么消息里常只放 ID | 搜索文档通常来自多张表,消费端按 ID 查主库最新快照可以减少乱序消息旧数据覆盖新数据,也让消息更小、更稳定。 | 消费端为什么要查 MySQL 最新快照 |
| ES 同步如何保证幂等 | 文档 _id 使用业务唯一 ID,消费重复消息时 upsert 同一文档;消费日志用 event_id 去重;删除和下架按主库状态判断;必要时记录版本号防止旧消息覆盖新消息。 | 幂等设计 |
| 如果 ES 更新失败怎么办 | 不能回滚 MySQL 主事务,也不能吞异常。先记录失败日志,区分网络超时、线程池拒绝、磁盘只读、Mapping 冲突等原因;可重试错误抛异常让 MQ 退避重试,超过次数进死信并告警;不可重试错误修正数据或 Mapping 后重放;最后用补偿任务对比 MySQL 和 ES 修复差异。 | ES 更新失败怎么办 |
| MQ 重复、乱序、丢失怎么处理 | 重复靠 event_id 和业务 _id 幂等;乱序靠查主库最新快照、版本号或按业务 key 顺序消费;丢失靠本地消息表、事务消息、CDC 位点、重试、死信和补偿对账。 | 失败窗口怎么分析、乱序控制 |
| ES 和主库不一致怎么办 | 先查 MySQL 当前值和 ES 文档,再查同步日志、MQ/CDC 延迟、死信、消费者异常、版本字段和补偿任务;修复方式是重试、死信重放、补偿扫描或全量重建。主库仍是事实来源。 | 线上排查流程 |
| 商品改价后 ES 还是旧价格怎么排查 | 先确认 MySQL 价格是否已变,再按 ID 查 ES 文档;如果 ES 还是旧值,查 MQ 堆积、消费失败、死信、旧消息覆盖、refresh 延迟和补偿任务;下单价格必须回商品服务或 MySQL 校验。 | 商品改价后 ES 还是旧价格 |
| 重建索引怎么做到不停机 | 业务访问别名;后台创建新索引,全量导入,增量追平,校验数量和核心查询结果,然后原子切换别名,观察后再删除旧索引。 | 零停机重建索引流程 |
性能与排查
| 面试题 | 标准回答 | 原理知识点 |
|---|---|---|
| 深分页为什么慢 | from + size 很大时,每个分片都要取大量候选结果,协调节点合并后再丢弃前面的数据,成本很高。可限制最大页数,使用 search_after 或 PIT。 | Query 与 Fetch |
| 查询慢怎么排查 | 先拿到最终 DSL 和 traceId,再看 slowlog 区分 Query 慢还是 Fetch 慢;用 profile 定位慢在倒排召回、filter、评分、排序、聚合还是某个分片;再看深分页、大聚合、wildcard、脚本排序、返回 _source 是否过大、高亮是否重、分片数量、磁盘 IO、CPU、GC、线程池拒绝。 | 查询慢排查、慢查询证据链 |
| Query 慢和 Fetch 慢怎么区分 | Query Phase 负责分片本地召回、过滤、评分、排序和协调节点合并 TopN;Fetch Phase 负责按 docId 拉取 _source、高亮和返回字段。Query 慢多看候选集、filter、sort、agg、script;Fetch 慢多看 _source 大小、高亮、大字段、inner_hits 和返回字段。 | 查询慢全过程、Query 与 Fetch |
| 写入慢怎么排查 | 看 Bulk 批次、并发、refresh、replica、merge、thread pool rejected、磁盘 IO 和 JVM GC。批量导入可临时调大 refresh、降低副本并控制并发。 | 写入慢排查 |
| 聚合慢怎么办 | 缩小查询范围,控制 bucket 数,使用 keyword/数值/date 字段,避免对 text 聚合;大盘统计可考虑预聚合或离线统计。 | 聚合慢 |
| 搜不到怎么排查 | 先查主库,再按 ID 查 ES 文档;如果 ES 没有查同步链路,如果有再查 Mapping、分词、term/match、filter、权限和 refresh。 | 搜不到排查 |
| 搜不准怎么排查 | 打印最终 DSL,用 _analyze 看分词,用 _explain 看评分,检查字段 boost、should、filter、同义词、业务排序和排序兜底字段。 | 搜不准排查 |
| 为什么不能把 ES DSL 直接暴露给前端 | 前端可构造深分页、大聚合、wildcard、脚本或绕过权限过滤,拖垮集群或造成越权。服务端应接收业务参数并翻译成受控 DSL。 | 搜索接口保护 |
| ES JVM 怎么关注 | 看 heap、old GC、circuit breaker、hot threads。ES 还依赖文件系统缓存,不是堆越大越好,大聚合和 fielddata 容易造成内存压力。 | JVM 和内存问题 |
商业场景题
| 面试题 | 标准回答 | 原理知识点 |
|---|---|---|
| 商品搜索索引怎么设计 | 不照搬商品表,而是按搜索页面设计文档,冗余商品名、卖点、品牌、类目、标签、价格、库存、销量、更新时间等字段,减少运行时 Join。 | 商业搜索场景 |
| 订单检索和商品搜索有什么不同 | 订单检索更偏精确条件、时间范围、权限过滤和稳定排序;商品搜索更偏全文召回、相关性、聚合筛选和运营排序。订单事实状态仍以主库为准。 | 商业搜索场景 |
| 日志索引怎么设计 | 日志通常按时间滚动索引,字段包含 traceId、service、level、path、message、costMs、timestamp,配合 ILM 做生命周期,避免磁盘无限增长。 | 商业搜索场景 |
| 搜索建议怎么做 | 可以用 search_as_you_type、ngram 或专门候选词索引,结合热度排序、脏词过滤和运营干预。不要用高成本 wildcard 去做所有输入提示。 | 商业搜索场景 |
| 医疗数据或资产平台怎么用 ES | 主库保存采集记录、资产元数据和治理结果,ES 保存搜索视图,用于按患者标识、检查项目、字段名、表名、标签、批次检索,并通过 MQ/CDC 和补偿保持最终一致。 | 商业搜索场景、同步与重建 |
项目话术
text
在医疗数据采集与资产平台里,我会把 MySQL 作为事实来源,把 ES 作为搜索视图。采集记录、资产元数据、字段中文名、表名、标签、批次、机构等信息会组装成面向检索的文档。业务写主库成功后,通过 MQ 或 CDC 同步到 ES,消费端按 ID 查主库最新快照再 upsert,失败进入重试和死信,定时补偿校验主库与 ES。查询侧由后端接收业务参数,统一加租户、权限、时间范围和状态过滤,再翻译成受控 DSL,避免前端直接暴露 ES 查询。常见追问
| 追问 | 回答方向 | 跳转 |
|---|---|---|
| ES 为什么快 | term dictionary 定位词,posting list 拿候选文档,filter bitset 做硬过滤,doc values 支撑排序聚合,分片并行后合并 TopN。 | 查询快的完整底层链路 |
| ES 为什么不是实时 | 写入后要 refresh 生成可搜索 segment。 | 写入、Refresh 与 Segment |
| 为什么商品改价后搜索还是旧价格 | 同步延迟、MQ 堆积、写 ES 失败、refresh 延迟、旧消息覆盖。 | 同步与重建 |
| 为什么加分片后反而慢 | 分片过多增加协调、元数据、恢复和小分片成本。 | 集群 |
| 为什么聚合字段用 keyword | keyword/doc values 适合精确值聚合,text 会分词,不适合直接聚合。 | Mapping与查询 |
| 怎么解释搜不到 | 主库、ES 文档、同步、Mapping、分词、DSL、filter 逐层排查。 | 性能优化与排查 |
| 怎么解释结果排序不合理 | 看 analyzer、BM25、字段 boost、should、业务排序和 _explain。 | 倒排索引与 BM25 |
| 重建索引为什么用别名 | 业务访问别名,新旧索引可原子切换和快速回滚。 | 同步与重建 |
本章小结
ES 面试回答要先定位:它是搜索和分析引擎,不是事务主库。然后讲核心原理:倒排索引、分词、Mapping、Query DSL、refresh、segment、分片副本、query/fetch、BM25。最后落到项目:MySQL 做事实源,ES 做搜索视图,通过 MQ/CDC 同步,别名重建索引,服务端保护 DSL,查询慢和搜不到按固定链路排查。
