在生产环境中,Elasticsearch 聚合查询的性能监控是保障数据分析系统稳定、高效运行的关键。不当的聚合设计可能导致高延迟、内存溢出(OOM)、节点负载过高等问题。
为此,我们设计一套 全面、可落地的 Elasticsearch 聚合性能监控看板,帮助你实时掌握聚合性能、识别瓶颈、优化查询。
一、目标与核心功能
| 目标 | 说明 |
|---|
| ✅ 实时监控聚合延迟 | 展示 P95/P99 延迟趋势 |
| ✅ 识别慢聚合查询 | 发现 terms、nested、cardinality 等高开销聚合 |
| ✅ 监控资源消耗 | fielddata、query cache 内存使用 |
| ✅ 分析缓存命中率 | request cache 命中率 |
| ✅ 可视化看板 | Grafana / Kibana 展示 TOP 榜单与趋势 |
| ✅ 告警机制 | 聚合延迟过高时通知 |
| ✅ 根因诊断 | 关联 JVM、线程池、分片状态 |
二、系统架构设计
+---------------------+
| Elasticsearch Cluster |
+----------+----------+
|
v
+------------------------+
| Exporter / Collector | ← 采集 _nodes/stats, _cat/indices, slowlog
+----------+-------------+
|
v
+------------------------+
| 时间序列数据库(TSDB) | → Prometheus / InfluxDB
+----------+-------------+
|
v
+------------------------+
| 告警引擎 & 可视化看板 | → Grafana / Kibana
+------------------------+
✅ 推荐使用 Elasticsearch Exporter for Prometheus
三、关键监控指标
1. 聚合延迟指标
| 指标 | 说明 |
|---|
elasticsearch_indices_search_fetch_time_seconds | 聚合结果获取阶段耗时(关键) |
elasticsearch_indices_search_fetch_total | fetch 次数 |
elasticsearch_indices_search_fetch_current | 正在执行的 fetch 数量 |
✅ 聚合耗时主要在 fetch 阶段。
2. Request Cache(聚合结果缓存)
| 指标 | 说明 |
|---|
elasticsearch_indices_request_cache_hit_count | 命中次数 |
elasticsearch_indices_request_cache_miss_count | 未命中 |
elasticsearch_indices_request_cache_evictions | 驱逐次数(内存不足) |
elasticsearch_indices_request_cache_memory_size_in_bytes | 内存占用 |
命中率 = hit / (hit + miss)
3. Fielddata Cache(排序/聚合字段缓存)
| 指标 | 说明 |
|---|
elasticsearch_indices_fielddata_memory_size_in_bytes | 内存使用 |
elasticsearch_indices_fielddata_evictions | 驱逐次数 |
elasticsearch_indices_fielddata_field_size_in_bytes | 按字段维度 |
⚠️ fielddata 使用堆内存,过高会导致 GC 频繁或 OOM。
4. 线程池压力
| 指标 | 说明 |
|---|
elasticsearch_thread_pool_search_queue | 搜索队列积压 |
elasticsearch_thread_pool_search_rejected | 搜索请求被拒绝 |
elasticsearch_thread_pool_search_active | 活跃线程数 |
队列积压表示节点处理不过来。
5. 慢聚合日志(可选)
启用慢日志,采集执行时间过长的聚合:
index.search.slowlog.threshold.fetch.warn: 5s
index.search.slowlog.threshold.fetch.info: 2s
通过 Filebeat 或 Logstash 收集并分析。
四、Grafana 看板设计
1. 主要面板
| 面板 | 内容 | 图表类型 |
|---|
| 📊 聚合延迟 P95/P99 | fetch_time_seconds 分位数 | Time series |
| 💾 Request Cache 命中率 | hit / (hit + miss) 趋势 | Time series |
| 📉 Request Cache 驱逐次数 | evictions 监控内存压力 | Bar chart |
| 🧱 Fielddata 内存使用 | 堆内存占用 | Gauge |
| ⚠️ Fielddata 驱逐次数 | 频繁驱逐表示 OOM 风险 | Time series |
| 🔁 搜索线程池队列 | search.queue 积压情况 | Time series |
| 🚫 搜索请求拒绝数 | search.rejected | Time series |
| 🐢 慢聚合 TOP 10 | 执行时间最长的聚合 | Table |
| 🧩 高开销聚合分布 | terms, nested, cardinality 占比 | Pie chart |
2. 核心 PromQL 查询
聚合延迟 P95
histogram_quantile(0.95, sum(rate(elasticsearch_indices_search_fetch_time_millis_bucket[5m])) by (le, job))
Request Cache 命中率
(
sum(rate(elasticsearch_indices_request_cache_hit_count[5m]))
)
/
(
sum(rate(elasticsearch_indices_request_cache_hit_count[5m])) +
sum(rate(elasticsearch_indices_request_cache_miss_count[5m]))
)
Fielddata 内存使用
elasticsearch_indices_fielddata_memory_size_in_bytes
搜索队列积压
elasticsearch_thread_pool_search_queue
搜索请求拒绝
rate(elasticsearch_thread_pool_search_rejected[5m])
五、健康阈值与告警标准
| 指标 | 健康 | 警告 | 危险 |
|---|
| 聚合延迟 P95 | < 500ms | 500ms~2s | > 2s |
| Request Cache 命中率 | > 70% | 30%~70% | < 30% |
| Fielddata 内存 | < 1GB | 1~2GB | > 2GB 或频繁驱逐 |
| 搜索队列 | < 10 | 10~100 | > 100 |
| 搜索拒绝 | 0 | < 5/min | > 5/min |
六、根因分析与优化建议
1. 高延迟常见原因
| 问题 | 诊断方法 | 修复建议 |
|---|
terms 聚合 size 过大 | 查看 terms.size | 限制 size: 100 |
nested 聚合 | 检查 mapping | 考虑反规范化 |
cardinality 精度高 | 检查 precision_threshold | 降低精度 |
fielddata 过大 | 监控 fielddata.memory | 改用 keyword + doc_values |
| 深度分页 | from > 10000 | 改用 composite 聚合 |
未用 filter | must 中有 term | 改为 bool.filter |
2. 告警规则设计(Prometheus)
- name: "Aggregation Latency Too High"
expr: |
histogram_quantile(0.95, sum(rate(elasticsearch_indices_search_fetch_time_millis_bucket[5m])) by (le)) > 2000
for: 5m
labels:
severity: critical
annotations:
summary: "聚合延迟过高"
description: "P95 聚合延迟 > 2s,请检查是否使用 fielddata 或大 size 聚合"
- name: "High Request Cache Evictions"
expr: rate(elasticsearch_indices_request_cache_evictions[5m]) > 10
for: 10m
labels:
severity: warning
- name: "Search Thread Pool Rejected"
expr: rate(elasticsearch_thread_pool_search_rejected[5m]) > 0
for: 2m
labels:
severity: critical
七、优化建议引擎(可选)
在看板中集成“优化建议”按钮,自动分析慢聚合并生成建议:
| 问题 | 建议 |
|---|
fielddata 使用 text 字段 | “请使用 field.keyword 聚合” |
terms size > 1000 | “限制 size,前端分页加载” |
nested 聚合 | “考虑将嵌套字段提升为根字段” |
| 未命中 request cache | “确保查询结构稳定,可缓存” |
八、部署方式
方案一:Prometheus + Grafana(推荐)
- 使用
elasticsearch_exporter 采集指标; - 存储到 Prometheus;
- Grafana 展示 + Alertmanager 告警。
方案二:Kibana + Metricbeat
- 使用 Metricbeat 监控 ES;
- 数据写入 ES 自身;
- Kibana 可视化。
九、最佳实践 checklist ✅
| 项目 | 建议 |
|---|
| 聚合字段 | 使用 keyword 而非 text |
terms 聚合 | 限制 size |
| 深度分页 | 使用 composite 聚合 |
| 高频聚合 | 启用 request cache |
监控 fielddata | 避免 OOM |
| 告警 | 延迟 > 2s 时告警 |
| 分析慢日志 | 定期审查慢聚合 |