一、性能与慢查询
1. ES 查询非常慢,延迟高
-
场景:用户反馈搜索接口经常超时,尤其在大分页查询时。
-
可能原因:
-
使用
from + size
进行深度分页,导致扫描大量文档。 -
没有使用合适的 keyword 字段,触发全文分析。
-
分片过多,节点压力大。
-
-
排查工具/方法:
-
/_cat/nodes?v
查看节点负载。 -
/_nodes/hot_threads
分析 CPU 占用。 -
/_tasks
查看慢查询任务。
-
-
解决方案:
-
使用
search_after
或scroll
替代深度分页。 -
在 mapping 中合理区分
text
与keyword
。 -
优化分片数量,减少不必要的广播查询。
-
2. ES 写入速度很慢
-
场景:日志数据写入,QPS 仅几千就触发瓶颈。
-
可能原因:
-
refresh_interval
太短,频繁 segment merge。 -
没用
bulk API
,单条写入开销大。 -
硬盘 IO 或 JVM GC 压力过大。
-
-
排查工具/方法:
-
_cat/indices?v
查看写入速率。 -
/_nodes/stats
检查 IO/GC。
-
-
解决方案:
-
批量写入(bulk),减少请求数。
-
调整
refresh_interval=30s
或临时设为-1
批量导入。 -
优化硬件(SSD)、调 JVM 堆。
-
3. 聚合查询(aggregation)导致内存溢出
-
场景:报表系统需要统计用户行为,ES 经常 OOM。
-
可能原因:
-
大量字段开启了
fielddata
。 -
使用了高基数字段(如 userId)做聚合。
-
-
排查工具/方法:
-
_cat/fielddata
查看内存使用。 -
/_nodes/stats?pretty
查看 JVM 内存分配。
-
-
解决方案:
-
将聚合字段设为
keyword
+doc_values
。 -
限制聚合深度(size)。
-
使用
composite aggregation
分页聚合。
-
二、索引与 Mapping
4. ES mapping 设计错误导致查询异常
-
场景:手机号存成了 text 类型,查询效率极差。
-
可能原因:
- 误用
text
,导致分词。
- 误用
-
排查工具/方法:
GET index/_mapping
查看字段类型。
-
解决方案:
-
修改 mapping 不可行,只能重建索引。
-
预先设计好字段(手机号/ID 用 keyword)。
-
5. 分片数设置不合理
-
场景:创建索引时设了 50 个分片,导致节点内存消耗大。
-
可能原因:
-
分片数量过多,导致资源浪费。
-
分片数量过少,导致无法扩展。
-
-
排查工具/方法:
/_cat/shards
查看分片分布。
-
解决方案:
-
计算分片数 ≈
数据量 / (单分片上限 50GB)
。 -
7.x 以后用 ILM(Index Lifecycle Management)自动管理索引滚动。
-
6. 索引占用磁盘过大
-
场景:100GB 原始数据,ES 占用 500GB。
-
可能原因:
-
_source
未禁用,存储重复 JSON。 -
没有压缩,字段冗余。
-
-
排查工具/方法:
_cat/indices?v
查看磁盘使用。
-
解决方案:
-
_source
只保留必要字段。 -
开启
best_compression
。 -
使用 alias 指向归档索引,定期清理历史数据。
-
三、集群与节点
7. 集群状态变成 yellow/red
-
场景:集群宕机后,索引部分不可用。
-
可能原因:
-
副本分片未分配。
-
Master 节点丢失。
-
-
排查工具/方法:
-
/_cluster/health
查看集群状态。 -
/_cat/allocation?v
查看分片分布。
-
-
解决方案:
-
增加节点,确保副本可分配。
-
检查 master 选举是否正常。
-
8. 集群频繁 GC,响应变慢
-
场景:查询稍微多一些,就频繁 Full GC。
-
可能原因:
-
JVM 堆过小。
-
fielddata 或聚合加载过多数据。
-
-
排查工具/方法:
-
jstat
、ES GC 日志
。 -
/_nodes/stats/jvm
查看内存。
-
-
解决方案:
-
调整 ES 堆大小(推荐 50% 内存,<=32G)。
-
用
doc_values
替代 fielddata。
-
9. 分片倾斜导致部分节点压力过大
-
场景:某些节点 QPS 很高,其他节点空闲。
-
可能原因:
- 分片分配不均匀。
-
排查工具/方法:
/_cat/shards
查看分布。
-
解决方案:
-
手动 reroute 分片。
-
配置
cluster.routing.allocation.awareness
,保证均衡。
-
10. 节点频繁掉线
-
场景:大查询时节点直接挂掉。
-
可能原因:
-
heap 内存不足。
-
网络分区。
-
-
排查工具/方法:
/_cluster/state
查看节点。
-
解决方案:
-
调整 JVM 堆 + OS 虚拟内存。
-
增加节点,避免单节点压力过大。
-
四、查询与业务应用
11. 中文搜索结果不准
-
场景:用户搜索"北京大学",结果却包含"北京 大学 城"。
-
可能原因:
- 默认 Standard Analyzer 不适合中文。
-
排查工具/方法:
_analyze
查看分词结果。
-
解决方案:
-
使用
IK 分词器
或jieba
。 -
搜索时使用
multi_match
并配置 analyzer。
-
12. 排序不稳定
-
场景:用户同样的搜索请求,每次结果顺序不同。
-
可能原因:
- 没有明确排序字段。
-
排查工具/方法:
- 检查查询 DSL 是否带
sort
。
- 检查查询 DSL 是否带
-
解决方案:
-
指定排序字段(如时间、权重)。
-
引入
_score
+ 二级排序。
-
13. 统计结果不准
-
场景:查询用户数,结果比真实数据少。
-
可能原因:
- ES 统计是近实时的,存在延迟。
-
排查工具/方法:
refresh
强制刷新。
-
解决方案:
-
关键业务场景下,调用
POST index/_refresh
。 -
允许弱一致性,减少性能损耗。
-
五、监控与运维
14. 查询 QPS 高,集群 CPU 100%
-
场景:业务高峰期 CPU 被打满,查询大量超时。
-
可能原因:
-
查询 DSL 复杂(wildcard、正则)。
-
节点不足。
-
-
排查工具/方法:
_nodes/hot_threads
找出热点查询。
-
解决方案:
-
优化 DSL,避免
*abc*
。 -
增加节点或分流。
-
15. ES 集群升级后,旧索引无法使用
-
场景:升级 ES 7.x 后,部分 5.x 索引报错。
-
可能原因:
- 跨大版本不兼容。
-
排查工具/方法:
_cat/indices
查看旧索引格式。
-
解决方案:
- 使用 reindex API 迁移数据。
16. 滚动日志索引过多
-
场景:日志索引每天建一个,1 年后有 365 个索引,管理困难。
-
可能原因:
- 没有生命周期管理策略。
-
排查工具/方法:
_cat/indices
查看索引数。
-
解决方案:
-
使用 ILM(Index Lifecycle Management)。
-
热数据用 SSD,冷数据迁移到 HDD 或 S3。
-
六、缓存与查询优化
17. 查询结果不稳定,性能忽高忽低
-
场景:同一查询第一次慢,第二次快。
-
可能原因:
- ES 使用了 query cache,第一次查询未命中缓存。
-
排查工具/方法:
/_nodes/stats/indices/query_cache
查看缓存命中率。
-
解决方案:
-
对热点查询使用缓存。
-
对动态查询参数禁用缓存。
-
18. 使用通配符查询(wildcard)非常慢
-
场景 :用户搜索
*abc*
,集群直接卡死。 -
可能原因:
- wildcard 会扫描大量 term。
-
排查工具/方法:
_explain
查看查询计划。
-
解决方案:
-
避免前缀
*
,改用 ngram 索引。 -
提前做关键词分词。
-
19. 正则查询耗时长
-
场景 :用
/abc.*/
匹配,耗时数十秒。 -
可能原因:
- 正则在倒排索引上效率差。
-
排查工具/方法:
profile API
分析查询性能。
-
解决方案:
-
用
keyword
字段 + 前缀匹配代替。 -
预处理业务字段,避免运行时正则。
-
20. 排序慢
-
场景:对 1000w 条数据排序,查询超时。
-
可能原因:
- 排序字段没用
doc_values
。
- 排序字段没用
-
排查工具/方法:
_mapping
查看字段属性。
-
解决方案:
-
对排序字段启用
doc_values
。 -
减少排序数据量(分页、分桶)。
-
七、Spring & 业务集成
21. Spring Boot + ES 查询延迟高
-
场景:接口层调用 ES 查询,RT 达 2s。
-
可能原因:
-
查询 DSL 过大。
-
HTTP 连接池配置不足。
-
-
排查工具/方法:
thread dump
查看等待队列。
-
解决方案:
-
使用
RestHighLevelClient
并调大连接池。 -
缓存热点查询。
-
22. MyBatis / JPA + ES 数据不同步
-
场景:更新 MySQL,ES 数据未更新。
-
可能原因:
- 缺少异步同步机制。
-
排查工具/方法:
- 对比 MySQL 和 ES 数据量。
-
解决方案:
-
使用 Canal/Kafka 捕获 Binlog → 写 ES。
-
定期做全量校验。
-
23. Kafka + ES 写入延迟大
-
场景:Kafka 消费写 ES 延迟几分钟。
-
可能原因:
- 批量提交太小,ES QPS 受限。
-
排查工具/方法:
- 查看 Kafka Lag。
-
解决方案:
-
批量 bulk 写入,调大并发。
-
调整 Kafka consumer 批量大小。
-
24. 日志链路丢失数据(ELK)
-
场景:日志收集不完整,部分数据不在 ES。
-
可能原因:
-
Logstash 队列溢出。
-
ES bulk 拒绝写入。
-
-
排查工具/方法:
-
logstash logs
。 -
/_cat/recovery
。
-
-
解决方案:
-
调大 Logstash 队列。
-
开启 bulk retry。
-
八、集群与跨数据中心
25. 跨集群搜索延迟高
-
场景:上海节点查询需要访问北京集群,延迟 2s。
-
可能原因:
- 网络延迟 + 跨集群广播。
-
排查工具/方法:
ping
/traceroute
网络检查。
-
解决方案:
-
业务侧缓存结果。
-
跨集群只查关键索引。
-
26. 跨机房写入失败
-
场景:双活 ES,跨机房写失败。
-
可能原因:
- ES 本身不支持多写一致性。
-
排查工具/方法:
_cluster/stats
。
-
解决方案:
-
采用消息队列中转(Kafka → 各机房 ES)。
-
单写多读架构。
-
27. 索引迁移失败
-
场景:索引从老集群迁移到新集群时报错。
-
可能原因:
- mapping 不兼容。
-
排查工具/方法:
_mapping
对比差异。
-
解决方案:
-
用 reindex API。
-
先迁空壳 mapping,再迁数据。
-
28. 索引恢复慢
-
场景:节点宕机重启后,索引恢复需数小时。
-
可能原因:
- 分片太大。
-
排查工具/方法:
/_cat/recovery?v
。
-
解决方案:
-
分片大小控制在 30~50GB。
-
多节点并行恢复。
-
29. 选主不稳定
-
场景:集群频繁触发 master 选举。
-
可能原因:
- master 节点数量不足。
-
排查工具/方法:
cluster logs
。
-
解决方案:
-
至少 3 个 master eligible 节点。
-
网络层优化,避免脑裂。
-
30. 集群健康状态频繁波动
-
场景:集群在 green/yellow 之间切换。
-
可能原因:
-
网络抖动。
-
节点负载过高。
-
-
排查工具/方法:
/_cluster/health?level=shards
。
-
解决方案:
-
调整
discovery.zen
配置。 -
增加资源。
-
九、容器化与运维
31. Docker 中 ES 内存不足
-
场景:ES 容器频繁 OOMKilled。
-
可能原因:
- JVM 堆设置不合理。
-
排查工具/方法:
docker stats
。
-
解决方案:
-Xms -Xmx
设置为 50% 容器内存。
32. Kubernetes 部署 ES 不稳定
-
场景:Pod 重启,集群频繁 yellow。
-
可能原因:
- PV 未绑定,数据丢失。
-
排查工具/方法:
kubectl describe pod
。
-
解决方案:
-
StatefulSet + PVC。
-
使用 local PV 或 Ceph。
-
33. ES 监控指标不全
-
场景:Prometheus 采集不到索引级别指标。
-
可能原因:
- 未安装 exporter。
-
排查工具/方法:
curl /_cat/indices
。
-
解决方案:
-
部署
elasticsearch-exporter
。 -
对接 Grafana。
-
34. 备份恢复失败
-
场景:ES snapshot 恢复报错。
-
可能原因:
- repository 配置错误。
-
排查工具/方法:
_snapshot/_status
。
-
解决方案:
-
使用 S3/HDFS repo。
-
确认权限。
-
35. 安全认证问题
-
场景:ES API 调用 401。
-
可能原因:
- X-Pack 未配置。
-
排查工具/方法:
/_security/user
。
-
解决方案:
-
配置 user/role。
-
使用 API key。
-
十、进阶问题
36. 热点索引写入瓶颈
-
场景:日志索引当天写入量过大。
-
可能原因:
- 所有写入落到单索引。
-
排查工具/方法:
/_cat/indices
。
-
解决方案:
-
按时间滚动索引(index per day)。
-
ILM 管理。
-
37. 热点 term 查询慢
-
场景:某用户 ID 查询慢。
-
可能原因:
- term 值过多。
-
排查工具/方法:
term stats
分析。
-
解决方案:
- 建立反向索引或预聚合表。
38. 聚合内存溢出
-
场景:大聚合任务 OOM。
-
可能原因:
- 一次性拉取太多 bucket。
-
排查工具/方法:
_tasks
。
-
解决方案:
-
composite agg 分批拉取。
-
限制 size。
-
39. Nested 查询性能差
-
场景:复杂对象嵌套查询很慢。
-
可能原因:
- nested 查询展开成多个 hidden doc。
-
排查工具/方法:
- profile API。
-
解决方案:
- 业务端扁平化存储。
40. pipeline aggregation 慢
-
场景:二次聚合计算慢。
-
可能原因:
- 处理了过多桶。
-
排查工具/方法:
- profile API。
-
解决方案:
- 限制前置聚合 bucket 数量。
十一、故障恢复与排查
41. 索引不可写
-
场景:磁盘 95%+,索引写入报错。
-
可能原因:
- ES 磁盘水位保护。
-
排查工具/方法:
_cluster/settings
。
-
解决方案:
-
扩容磁盘。
-
修改
cluster.routing.allocation.disk.watermark.*
。
-
42. ES 无法启动
-
场景:重启 ES 失败。
-
可能原因:
- 权限不足 / jvm.options 错误。
-
排查工具/方法:
- logs 目录。
-
解决方案:
-
检查
vm.max_map_count
。 -
调整 jvm 参数。
-
43. 集群分裂(脑裂)
-
场景:出现多个 master。
-
可能原因:
- 网络分区。
-
排查工具/方法:
- cluster logs。
-
解决方案:
- 配置
discovery.zen.minimum_master_nodes = N/2+1
。
- 配置
44. ES 滚动升级失败
-
场景:升级版本后部分节点不兼容。
-
可能原因:
- 跨大版本不支持。
-
排查工具/方法:
- logs。
-
解决方案:
-
逐级升级。
-
先升级 master 节点。
-
45. 数据丢失
-
场景:节点宕机,部分索引丢失。
-
可能原因:
- 没有副本。
-
排查工具/方法:
/_cat/indices
。
-
解决方案:
-
生产至少 1 副本。
-
快照备份。
-
46. 查询超时
-
场景:接口调用 30s 超时。
-
可能原因:
- 搜索条件不走倒排索引。
-
排查工具/方法:
- explain API。
-
解决方案:
-
优化 mapping。
-
避免 script 查询。
-
47. Script 查询性能差
-
场景:脚本评分查询卡顿。
-
可能原因:
- script 每次编译。
-
排查工具/方法:
- script logs。
-
解决方案:
- 使用 painless 并启用 script 缓存。
48. ES 节点磁盘写满
-
场景:磁盘满导致宕机。
-
可能原因:
- segment merge 写放大。
-
排查工具/方法:
_cat/allocation
。
-
解决方案:
- 增加磁盘或清理旧索引。
49. 备份恢复很慢
-
场景:snapshot restore 需要数小时。
-
可能原因:
- 网络带宽不足。
-
排查工具/方法:
- repo logs。
-
解决方案:
-
并行恢复多个 shard。
-
提前冷热分离。
-
50. ES 在大数据场景下不稳定
-
场景:100TB 数据集群经常 red。
-
可能原因:
-
分片太多。
-
节点负载过高。
-
-
排查工具/方法:
/_cluster/stats
。
-
解决方案:
-
用冷热分离架构。
-
使用 rollup / spark 分析。
-