在 Elasticsearch 高并发搜索场景中,查询缓存命中率是衡量系统性能与资源利用效率的关键指标。高缓存命中率意味着:
- 更少的磁盘 I/O;
- 更低的 CPU 消耗;
- 更快的查询响应;
- 更高的集群吞吐。
为此,我们设计一套 Elasticsearch 查询缓存命中率监控看板,帮助你实时掌握缓存使用情况,优化查询设计。
一、目标与核心功能
| 目标 | 说明 |
|---|---|
| ✅ 实时监控缓存命中率 | 展示 query、request、fielddata 缓存命中率 |
| ✅ 识别低效查询 | 发现未命中缓存的高频查询 |
| ✅ 分析缓存压力 | 监控内存使用、驱逐(evictions)情况 |
| ✅ 可视化看板 | Grafana / Kibana 展示趋势与 TOP 榜单 |
| ✅ 告警机制 | 缓存命中率过低时告警 |
| ✅ 优化建议 | 提供提升命中率的调优建议 |
二、Elasticsearch 缓存类型
Elasticsearch 主要有三种可缓存组件:
| 缓存类型 | 说明 | 是否可配置 |
|---|---|---|
| Query Cache | 缓存 filter 上下文的结果(bitset) | ✅ |
| Request Cache | 缓存整个查询的聚合结果 | ✅ |
| Fielddata Cache | 加载 text 字段用于排序/聚合(堆内内存) | ⚠️ 尽量避免 |
✅ Query Cache 和 Request Cache 是我们监控的重点。
三、关键监控指标
1. Query Cache 指标
| 指标 | 说明 |
|---|---|
query_cache.hit_count | 命中次数 |
query_cache.miss_count | 未命中次数 |
query_cache.evictions | 被驱逐次数(内存不足) |
query_cache.memory_size_in_bytes | 占用内存 |
命中率 =
hit / (hit + miss)
2. Request Cache 指标
| 指标 | 说明 |
|---|---|
request_cache.hit_count | 聚合结果命中 |
request_cache.miss_count | 未命中 |
request_cache.evictions | 驱逐次数 |
request_cache.memory_size_in_bytes | 内存占用 |
适用于“聚合结果不变”的查询。
3. Fielddata Cache 指标
| 指标 | 说明 |
|---|---|
fielddata.memory_size_in_bytes | 内存使用 |
fielddata.evictions | 频繁驱逐表示 OOM 风险 |
⚠️ 应尽量避免使用
fielddata。
四、系统架构设计
+---------------------+
| Elasticsearch Cluster |
+----------+----------+
|
v
+------------------------+
| Exporter / Collector | ← 通过 _nodes/stats 采集缓存指标
+----------+-------------+
|
v
+------------------------+
| 时间序列数据库(TSDB) | → Prometheus / InfluxDB
+----------+-------------+
|
v
+------------------------+
| 告警引擎 & 可视化看板 | → Grafana / Kibana
+------------------------+
五、Prometheus 配置示例
scrape_configs:
- job_name: 'elasticsearch'
static_configs:
- targets: ['es-node1:9200', 'es-node2:9200']
metrics_path: /_prometheus/metrics
scheme: http
basic_auth:
username: 'monitor'
password: 'password'
或使用 Telegraf、Metricbeat 采集。
六、Grafana 看板设计
1. 主要面板
| 面板 | 内容 | 图表类型 |
|---|---|---|
| 📊 Query Cache 命中率 | hit / (hit + miss) 趋势 | Time series |
| 📊 Request Cache 命中率 | 聚合缓存命中率 | Time series |
| 📉 Cache Evictions | 驱逐次数(越高越差) | Bar chart |
| 💾 Cache 内存使用 | query/request cache 内存占用 | Gauge |
| 🔁 Cache 清理频率 | evictions / minute | Time series |
| 🧩 按索引缓存命中率 | 各索引命中率对比 | Table |
| 🚨 低命中率查询 TOP 10 | 未命中缓存的高频查询 | Table |
2. 核心 PromQL 查询
Query Cache 命中率
(
sum(rate(elasticsearch_indices_query_cache_hits_total[5m]))
)
/
(
sum(rate(elasticsearch_indices_query_cache_hits_total[5m])) +
sum(rate(elasticsearch_indices_query_cache_misses_total[5m]))
)
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]))
)
Cache 内存使用
elasticsearch_indices_query_cache_memory_size_in_bytes
elasticsearch_indices_request_cache_memory_size_in_bytes
驱逐次数(Evictions)
rate(elasticsearch_indices_query_cache_evictions[5m])
rate(elasticsearch_indices_request_cache_evictions[5m])
七、命中率健康标准
| 缓存类型 | 健康 | 警告 | 危险 |
|---|---|---|---|
| Query Cache | > 80% | 50%~80% | < 50% |
| Request Cache | > 70% | 30%~70% | < 30% |
| Fielddata | 0(禁用) | < 1GB | > 2GB 或频繁驱逐 |
✅ 生产环境应尽量让 Query Cache 命中率 > 80%。
八、低命中率根因分析
| 问题 | 表现 | 修复建议 |
|---|---|---|
使用 must 而非 filter | query cache 未命中 | 改为 bool.filter |
wildcard/regexp 查询 | 每次不同,无法缓存 | 改用 prefix 或 ngram |
now 动态时间 | range: {gte: "now-1h"} | 改为固定时间窗口 |
| 高频更新文档 | _version 变化导致缓存失效 | 减少非必要更新 |
聚合字段用 text | 启用 fielddata,不进 request cache | 改用 keyword |
九、告警规则设计
1. 告警规则(Prometheus Alertmanager)
- name: "Query Cache Hit Rate Too Low"
expr: |
(
sum(rate(elasticsearch_indices_query_cache_hits_total[5m]))
)
/
(
sum(rate(elasticsearch_indices_query_cache_hits_total[5m])) +
sum(rate(elasticsearch_indices_query_cache_misses_total[5m]))
)
< 0.5
for: 5m
labels:
severity: warning
annotations:
summary: "Query Cache 命中率过低"
description: "当前命中率 < 50%,请检查是否使用 filter 上下文"
- name: "High Cache Evictions"
expr: rate(elasticsearch_indices_query_cache_evictions[5m]) > 10
for: 10m
labels:
severity: critical
十、优化建议引擎
当命中率低时,自动生成建议:
| 问题 | 建议 |
|---|---|
must 中有精确匹配 | “将 term/range 条件移入 bool.filter” |
使用 wildcard | “建议使用 prefix 或 completion” |
now 时间范围 | “改为 2024-06-01T00:00:00Z 固定值” |
聚合用 text 字段 | “请使用 field.keyword 聚合” |
可集成到看板中,提供“优化建议”按钮。
十一、部署方式
方案一:Prometheus + Grafana(推荐)
- 使用
elasticsearch_exporter采集指标; - 存储到 Prometheus;
- Grafana 展示 + Alertmanager 告警。
方案二:Kibana + Metricbeat
- 使用 Metricbeat 监控 ES;
- 数据写入 ES 自身;
- Kibana 可视化。
十二、最佳实践 checklist ✅
| 项目 | 建议 |
|---|---|
| 启用 Query Cache | 默认开启 |
| 高频过滤条件 | 放入 bool.filter |
避免 wildcard/regexp | 改用 prefix 或预处理 |
| 固定时间范围 | 避免 now |
监控 evictions | 高频驱逐需扩容 |
| 聚合字段 | 使用 keyword,避免 fielddata |
| 告警 | 命中率 < 50% 时告警 |
Elasticsearch查询缓存命中率监控看板方案
2446

被折叠的 条评论
为什么被折叠?



