Elasticsearch 八股题库
这份题库重点不是“会不会调几个 DSL”,而是让你能把 Elasticsearch 讲成:
- 为什么适合全文检索
- 为什么不适合做主事务库
- 倒排索引到底快在哪里
- 分片、副本、refresh、merge 这些原理和工程问题怎么串起来
一、Elasticsearch 面试里你的最佳定位
你最稳的说法是:
我对 Elasticsearch 的理解,不是停留在建索引和写 DSL,而是知道它为什么适合承接搜索和检索型查询,也知道它和 MySQL 的职责边界,以及索引构建、分片、副本、刷新和数据同步这些治理问题。
二、高频题
1. Elasticsearch 为什么搜索快
标准回答
核心原因是倒排索引。 它不是按“文档 -> 包含哪些词”去查,而是按“词 -> 出现在哪些文档”去组织数据。
你可以补的点
- 全文检索本质上是先分词
- 每个 term 都维护 posting list
- 查关键词时直接命中对应 term 的倒排链
- 不需要像数据库
like '%xx%'那样大量扫数据
面试更稳的说法
ES 快的核心不是某条 DSL 很高级,而是底层倒排索引把查找路径提前组织好了。
2. 什么是倒排索引
标准回答
倒排索引是按 term 建索引,记录每个 term 出现在哪些文档中。
简单例子
有三篇文档:
- 文档 1:
apple phone - 文档 2:
apple watch - 文档 3:
android phone
倒排索引会更像:
apple -> [1, 2]phone -> [1, 3]watch -> [2]android -> [3]
所以搜 apple 时,直接能拿到文档 1 和文档 2。
3. Elasticsearch 和 MySQL 的核心区别是什么
标准回答
- MySQL 更适合事务型主数据
- Elasticsearch 更适合全文检索、复杂搜索和检索型聚合
面试更稳的说法
MySQL 的核心能力是事务、一致性和主状态;ES 的核心能力是搜索、过滤、排序和检索型查询。
项目里怎么讲
像商品搜索、批量导入后的检索、后台多条件筛选、搜索推荐这类场景,我会优先考虑 ES;但订单、支付、退款、订阅这些主状态一定还是回 MySQL。
4. 为什么说 ES 不适合做主库
标准回答
因为它不是为强事务、强一致主状态设计的。
你可以补的点
- 默认更偏近实时而不是强实时
- 主状态更新链路通常没有 MySQL 那么稳
- 写入、刷新、分片、副本同步都更偏搜索引擎思路
- 适合“查得快”,不适合“拿来做唯一真实状态”
面试更稳的说法
ES 非常适合查,但不应该成为订单、支付、退款这种业务主状态的唯一事实来源。
5. text 和 keyword 有什么区别
标准回答
text:会分词,适合全文检索keyword:不分词,适合精确匹配、聚合、排序、过滤
例子
字段 name = "Apple Watch Ultra":
text适合搜applekeyword适合精确过滤整个字符串
面试更稳的说法
很多字段都应该同时建:
- 一个
text负责搜索 - 一个
keyword子字段负责过滤和排序
6. 分词器 analyzer 是干什么的
标准回答
分词器负责把文本拆成一个个 term,并决定:
- 怎么切词
- 是否转小写
- 是否去停用词
- 是否做同义词处理
面试更稳的说法
ES 搜索效果很大程度上不只是 DSL,而是 analyzer 设计得对不对。 搜索不准,很多时候根因是分词和 mapping 设计有问题。
7. shard 和 replica 是什么
标准回答
shard:分片,把一个索引拆成多个数据片段replica:副本,复制主分片的数据,用于高可用和读扩展
面试更稳的说法
分片解决的是容量和并行问题,副本解决的是可用性和读能力问题。
注意点
- 分片不是越多越好
- 分片太多会带来管理、内存和查询协调成本
8. refresh、flush、merge 分别是什么
标准回答
refresh:让新写入的数据对搜索可见flush:把内存中的数据和事务日志状态更稳定地落盘merge:把多个小 segment 合并,减少碎片和查询开销
面试更稳的理解
这三个动作分别更偏:
- 搜索可见性
- 持久化阶段
- 长期查询性能和索引整理
你不能把 refresh 理解成“已经彻底安全落盘”,它更偏近实时搜索可见。
9. 为什么说 ES 是近实时搜索
标准回答
因为文档写入后,不一定立刻就能被搜索到,通常要等 refresh 之后才能被检索命中。
面试更稳的说法
ES 更像“很快可查”,但不是数据库事务那种提交即强一致可见。
10. 查询流程大概是怎样的
标准回答
一次搜索大致会经历:
- 协调节点接收请求
- 把请求分发到相关分片
- 各分片本地执行 query
- 汇总排序
- 再 fetch 文档详情
- 返回最终结果
面试更稳的说法
ES 搜索往往不只是“查一个点”,而是多分片并行查询后再统一归并结果。
11. ES 写入流程大概是怎样的
标准回答
简化理解可以是:
- 文档写到主分片
- 写入内存缓冲和 translog
- 同步到副本分片
- refresh 后对搜索可见
面试更稳的说法
写入成功不等于立刻搜索可见,这就是为什么 ES 更偏近实时。
12. 搜索慢一般怎么排
标准回答
常见排查方向:
- 查询 DSL 是否太复杂
- 分片数是否过多
- mapping 是否合理
- 是否排序 / 聚合过重
- 是否命中过滤缓存
- 是否有深分页
你可以补的点
- 看是不是
text/keyword设计错误 - 看是不是一边全文检索一边大量聚合
- 看是不是深分页
from + size太大 - 看是不是热点索引或 segment 太碎
面试更稳的说法
ES 慢很多时候不是单点问题,而是 mapping、查询 DSL、分片设计和数据规模一起叠加出来的。
13. 深分页为什么慢
标准回答
因为 from + size 很大时,ES 需要先取出前面大量结果再丢弃,成本很高。
常见优化
search_after- scroll
- 限制最大分页深度
- 改交互方式,不让用户无限翻页
更完整一点怎么讲
1. 为什么 from + size 在 ES 里尤其贵
因为 ES 通常不是一台机器查完就结束,而是多分片并行查询。
当你查一个很靠后的页时,常见过程是:
- 每个 shard 先找出自己前
from + size条候选 - 协调节点再把所有 shard 的候选结果做全局归并排序
- 最后前面的
from大量结果被直接丢掉
所以深分页真正贵的不是“最后只返回 10 条”,而是:
- shard 端要维护更大的候选集合
- 协调节点要 merge 更多结果
- 排序、内存和 CPU 压力都会上升
2. 为什么默认只让你翻到 10000 条左右
这不是随便拍脑袋的限制,而是为了保护集群。
ES 默认会用:
index.max_result_window = 10000
去限制 from + size 的深度,防止某个深分页请求把整条搜索链路拖得很重。
3. search_after 是什么
search_after 可以理解成“基于上一页最后一条结果的游标分页”。
它不是每次都从第 1 页重新跳过前面几万条,而是:
- 先拿第一页
- 记住最后一条文档的 sort 值
- 下一页从这个 sort 值之后继续查
所以它更像:
- 顺着结果继续往后翻
而不是:
- 每次都重算前面所有页再丢掉
4. search_after 适合什么,不适合什么
适合
- “下一页”
- “加载更多”
- 无限滚动
不适合
- 随意跳到第 378 页
- query 和 sort 经常变化
因为它依赖:
- 相同的 query
- 相同的 sort
- 上一页最后一条的排序值
5. 为什么经常说 search_after 最好配合 PIT
如果翻页过程中索引发生 refresh 或文档变化,结果顺序可能漂。
这时候会出现:
- 重复
- 漏数据
- 页与页之间不稳定
PIT,也就是 point in time,可以理解成:
- 在这次分页过程中固定一个索引视图
所以更稳的组合通常是:
search_after + PIT
6. scroll 是什么,为什么不推荐拿它做前台深分页
scroll 更像“批量扫描 / 离线导出 / 重建索引”的工具。
适合:
- 全量导出
- 批处理
- 后台任务
不适合:
- 用户前台实时翻页
- 搜索结果页一页页点下去
因为 scroll 会维护服务端上下文,它更偏“遍历数据”,不是“交互式分页”。
7. 为什么“限制最大分页深度”本身也是优化
很多时候真正的问题不是 ES 不够快,而是产品交互不适合搜索系统。
比如:
- 让用户跳到第 500 页
- 在几十万结果里无限翻页
这类需求本身就不太适合搜索产品。
更合理的做法通常是:
- 只保留浅分页
- 改成“加载更多”
- 强化筛选条件
- 导出需求走异步导出
一段更像做过项目的回答
ES 深分页慢,不只是因为 from 很大,而是因为它是多分片查询。每个 shard 都要先拿出前 from+size 条候选,再由协调节点做全局归并和排序,所以越往后,内存和 CPU 成本越高。我的做法通常是:普通浅分页继续用 from+size;连续翻页用 search_after;如果要保证翻页期间结果稳定,就配 PIT;全量导出走 scroll;同时限制最大分页深度,不让用户无限翻页。
14. ES 和数据库同步一般怎么做
标准回答
常见做法:
- 业务写 MySQL
- 通过 MQ / Canal / binlog / 异步任务同步到 ES
面试更稳的说法
我一般会让 MySQL 做主状态,ES 做查询镜像,通过异步链路同步,接受短暂延迟,但不让 ES 反过来定义主状态。
15. 项目里怎么讲 ES 更自然
你可以说:
我项目里对 ES 的使用重点不是“会不会搭”,而是把它放在正确的位置。像搜索、筛选、批量导入后的检索、后台复杂查询,ES 很适合;但订单、支付、退款、订阅这些强状态链路,主事实仍然要在 MySQL。
三、你最该主动讲的 ES 项目化理解
1. ES 适合放什么
- 商品 / 内容搜索
- 多条件检索
- 后台复杂筛选
- 导入后快速查询
2. ES 不适合放什么
- 支付主状态
- 订单主状态
- 退款主状态
- 强事务核心数据
3. ES 的核心价值
不是“什么都能存”,而是:
- 全文检索
- 检索性能
- 搜索排序
- 过滤聚合
四、常见追问
追问 1:为什么不是所有查询都交给 ES
可以答:
因为 ES 的强项是搜索和检索,不是主状态事务。不是所有查询慢都应该甩给 ES,要先看它是不是搜索问题。
追问 2:ES 和 ClickHouse 有什么区别
可以答:
ES 更偏搜索和检索型查询,ClickHouse 更偏分析型聚合。一个更像搜索引擎,一个更像分析数据库。
追问 3:ES 数据不一致怎么办
可以答:
先接受它作为查询镜像的最终一致性定位,再通过 MQ、补偿任务、重建索引和对账机制把同步链路做稳。
五、你复习 ES 最该背的 10 个点
- 倒排索引
- 为什么搜索快
- text / keyword
- analyzer / 分词
- shard / replica
- refresh / flush / merge
- 近实时搜索
- 查询流程
- 深分页
- MySQL 和 ES 的职责边界