Elasticsearch高频“学习”题总结
约 2229 字大约 7 分钟
Elasticsearch 高频“学习”题 (30+)
1. 什么是 Elasticsearch?使用场景?
- 定义:基于 Lucene 的分布式、RESTful 风格的搜索和数据分析引擎。
- 场景:
- 全文检索:电商商品搜索、站内搜索。
- 日志分析:ELK Stack(Elasticsearch + Logstash + Kibana)收集分析日志。
- 数据分析:近实时的复杂聚合分析。
2. 什么是倒排索引(Inverted Index)?
- 正排索引:文档 ID -> 关键词(如 MySQL 主键查找)。
- 倒排索引:关键词 -> 文档 ID 列表。
- 原理:将文档内容进行分词,建立“词”到“文档 ID”的映射关系。搜索时,根据关键词快速找到包含该词的文档列表。
3. Elasticsearch 的核心概念有哪些?
- Index(索引):类似于 MySQL 的 Database(或 Table,7.x 后更像 Table)。
- Document(文档):类似于 MySQL 的 Row(一行数据),JSON 格式。
- Field(字段):类似于 MySQL 的 Column。
- Node(节点):一台 ES 服务器。
- Cluster(集群):多台 Node 组成。
- Shard(分片):数据的水平切分,分布在不同节点。
- Replica(副本):分片的备份,提高可用性和读取吞吐量。
4. 为什么要分片(Shard)和副本(Replica)?
- 分片:
- 水平扩展:解决单机存储容量和性能瓶颈。
- 并行处理:查询时在多个分片并行执行,提高速度。
- 副本:
- 高可用:主分片挂了,副本分片升为主分片。
- 负载均衡:副本分片可以承担读请求,提升吞吐量。
5. Elasticsearch 的写入流程?
- 客户端请求发给任意节点(Coordinating Node)。
- 节点根据路由算法(
hash(id) % shard_num)找到主分片(Primary Shard)。 - 主分片写入:
- 先写入 Memory Buffer(内存缓冲区)。
- 同时写入 Translog(事务日志,防止数据丢失)。
- Refresh:每隔 1s,Buffer 中的数据生成新的 Segment(段)文件,并进入 OS Cache,此时数据可见(可被搜索)。
- 同步副本:主分片并发发给副本分片。
- Flush:每隔 30min 或 Translog 过大,触发 Flush,将 Segment 刷入磁盘,清空 Translog。
6. Elasticsearch 的读取流程(Get vs Search)?
- Get(按 ID 查询):
- 计算路由,直接去对应分片(主或副本)读取。
- Search(关键词查询):
- Query 阶段:协调节点将请求发给所有分片。各分片本地查询,返回文档 ID 和分数。
- Fetch 阶段:协调节点合并结果,排序,根据 ID 去各分片拉取完整文档。
7. 什么是近实时(NRT)?
- 写入的数据默认需要 1秒(refresh_interval)后才能被搜索到。
- 因为数据先写 Buffer,生成 Segment 放入 OS Cache 后才可见,而不是直接落盘。
8. 什么是 Lucene 的 Segment?为什么要合并?
- Segment:倒排索引的物理存储单元,不可变。
- 原因:每秒 Refresh 都会生成一个小 Segment,文件数量会爆炸,影响查询性能(因为要遍历所有 Segment)。
- 合并(Merge):后台线程自动将小 Segment 合并成大 Segment,并物理删除被标记为删除的文档。
9. Elasticsearch 如何删除和更新文档?
- 逻辑删除:Segment 不可变,删除只是在
.del文件中标记该文档 ID 为 deleted。 - 更新:先标记删除,再插入新文档。
- 物理删除:在 Segment Merge 阶段,被标记删除的文档才会被真正清理。
10. 什么是脑裂(Split-Brain)?如何解决?
- 现象:网络分区导致集群分成了两个,产生了两个 Master,数据不一致。
- 解决:配置
discovery.zen.minimum_master_nodes=(master_eligible_nodes / 2) + 1。保证选举 Master 需要半数以上节点同意。(7.x 后已内置 Raft 算法,无需手动配置)。
11. Text 和 Keyword 类型区别?
- Text:会分词。支持全文检索,不支持聚合和排序(除非开启 fielddata,费内存)。
- Keyword:不分词。作为整体存储,支持精确匹配、聚合和排序。
12. Term 查询和 Match 查询的区别?
- Term:精确查询。查询词不分词,直接去倒排索引找完全匹配的词。
- Match:全文检索。查询词会被分词器拆分,然后去倒排索引找匹配的词。
13. Filter(过滤)和 Query(查询)的区别?
- Query:关注“文档匹配度是多少”,计算 Score(相关性得分)。
- Filter:关注“文档是否匹配”,不计算分数,且结果会被缓存,性能更高。
14. 什么是 Doc Values?
- 列式存储结构,默认开启。
- 存储在磁盘,用于排序(Sorting)、聚合(Aggregation) 和 脚本访问。
- 倒排索引适合搜索,Doc Values 适合分析。
15. 分页查询的深分页问题(Deep Paging)?
from + size很大时(如查第 10000 页),每个分片都要查前 10000+size 条数据,协调节点要合并所有分片的结果(排序),内存和 CPU 消耗巨大。- ES 默认限制
max_result_window为 10000。
16. 如何解决深分页问题?
- Scroll:游标查询。生成快照,适合全量导出,不适合实时查询。
- Search After:基于上一页最后一条数据的排序值查下一页。适合实时深分页(类似于移动端下拉加载)。
17. 聚合(Aggregation)有哪些类型?
- Metric(指标):计算值,如 Max, Min, Avg, Sum, Stats。
- Bucket(桶):分组,如 Terms(按字段分组), Range(按范围分组), Date Histogram(按时间直方图)。
- Pipeline:对聚合结果再聚合。
18. Elasticsearch 性能调优建议?
- 硬件:SSD 磁盘,大内存(Heap 分配内存的一半,留一半给 OS Cache)。
- 写入优化:批量写入(Bulk),增加 Refresh 间隔(减少 Segment),禁用 Swap。
- 查询优化:多用 Filter,路由(Routing),避免深分页。
19. 什么是 Translog?
- 事务日志。
- 保证数据持久性。写入 Buffer 的同时写入 Translog。
- 即使机器宕机,内存数据丢了,重启后可以从 Translog 恢复。
20. 什么是分析器(Analyzer)?
- 用于将文本转换为词条(Token)流。
- 组成:
- Character Filter:字符过滤(如去 HTML 标签)。
- Tokenizer:分词(如按空格切分)。
- Token Filter:词条过滤(如转小写、去停用词)。
21. 什么是 IK 分词器?
- 中文分词插件。
- ik_max_word:细粒度切分(“中华人民共和国” -> “中华”、“华人”、“人民”...)。
- ik_smart:粗粒度切分(“中华人民共和国” -> “中华人民共和国”)。
22. 索引模板(Index Template)的作用?
- 预先定义好 Setting 和 Mapping。
- 当创建新索引(如日志按天生成
log-2023.10.01)时,自动匹配模板应用配置,无需每次手动设置。
23. Mapping 能否动态修改?
- 新字段:可以添加。
- 旧字段:不能修改(如从 Text 改为 Keyword)。因为倒排索引已生成,修改会导致无法搜索。
- 解决:新建索引(正确 Mapping)+ Reindex(数据迁移)。
24. Elasticsearch 集群状态颜色含义?
- Green:所有主分片和副本分片都正常。
- Yellow:所有主分片正常,但有部分副本分片未分配(单节点集群常态)。
- Red:有主分片未分配,部分数据丢失或不可用。
25. Elasticsearch 在海量数据下如何优化写入?
- Bulk:批量请求。
- 多线程:并发写入。
- Refresh Interval:调大(如 30s),减少 Segment 生成。
- Replica:首次导入时设为 0,导完再开启。
- Translog:改为异步刷盘(
request->async,牺牲一致性换性能)。
26. 什么是 Routing(路由)?
- 决定文档存储在哪个分片。
- 默认:
hash(id) % shard_num。 - 自定义:
POST /index/_doc?routing=user_id。 - 优点:查询时指定 Routing,只需查这一个分片,不用查所有分片。
27. Elasticsearch 的选主流程(ZenDiscovery)?
- 节点启动,Ping 其他节点。
- 找到 Master 候选节点(node.master: true)。
- 比较:先比 ClusterState 版本(谁的数据新),再比 ID(谁的 ID 小)。
- 投票:得票过半者当选。
28. 什么是 Ingest Node?
- 数据预处理节点。
- 在数据写入索引之前,对数据进行转换(如解析 JSON、IP 转经纬度),类似于 Logstash 的 Filter 功能,但更轻量。
29. 倒排索引不可变(Immutable)有什么好处?
- 不需要锁:并发读不需要加锁。
- 缓存友好:OS Cache 可以很好地缓存索引文件。
- 压缩:可以进行高效的压缩。
- 缺点:更新数据需要生成新段,需定期合并。
30. Elasticsearch 如何保证数据一致性(Write Consistency)?
wait_for_active_shards参数。- 写入时,要求多少个分片(主+副本)是活跃的才允许写入。
- 默认为 1(只要主分片在就行),可设为
all或quorum。
31. 什么是 Frozen Index(冻结索引)?
- 针对极少查询的历史数据。
- 索引即使 Open 也不占用 Heap 内存,而是按需从磁盘加载。
- 查询慢,但能极大节省内存,单节点可挂载更多数据。
