ElasticsearchNotes

第 29 章:监控告警

zjc 于 2026-01-29 发布

这是《Elasticsearch 零基础实战指南》的独立章节版。本章从概念、实操和生产排查三个视角展开,代码块保留了原书可直接运行的版本。 监控的目标不是画很多图,而是在问题影响业务前发现它,并在事故中快速回答四个问题:影响面多大、瓶颈在哪、先做什么、什么时候恢复。

本章建立 Elasticsearch 的监控体系:集群、节点、索引、查询、写入、JVM、磁盘和告警 Runbook。

29.1 监控分层

层级 关注问题 常用 API
集群 健康、节点、分片、master _cluster/health
节点 CPU、内存、磁盘、线程池 _nodes/stats
索引 写入、查询、段、合并 _stats
分片 大小、文档数、未分配 _cat/shards
请求 延迟、失败、慢查询 slowlog、APM
采集链路 lag、失败、重试 Kafka、Filebeat、OTel
业务 无结果率、搜索成功率 应用日志

常用快照:

GET /_cluster/health?pretty
GET /_cat/nodes?v
GET /_cat/indices?v&health=yellow
GET /_cat/allocation?v
GET /_cat/thread_pool/write,search?v&h=node_name,name,active,queue,rejected

生产监控建议通过 Prometheus 采集,而不是人肉执行 Cat API。

29.2 集群健康

GET /_cluster/health?timeout=5s

关键字段:

字段 含义
status green/yellow/red
number_of_nodes 当前节点数
number_of_data_nodes 数据节点数
active_primary_shards 主分片数
active_shards 主副本总数
unassigned_shards 未分配分片
initializing_shards 恢复中分片
relocating_shards 迁移中分片
delayed_unassigned_shards 延迟分配分片
pending_tasks master 队列
max_task_wait_time 最长任务等待

告警示例:

条件 级别
status=red 持续 1 分钟 P0/P1
status=yellow 持续 10 分钟 P2
number_of_nodes 低于期望 P1
pending_tasks > 50 持续 5 分钟 P2
unassigned_shards 增加 P2
master 变更 P1

29.3 节点指标

查看节点统计:

GET /_nodes/stats/jvm,os,fs,indices,thread_pool?human

29.3.1 CPU 与负载

关注:

CPU 高的常见原因:

29.3.2 JVM

关注:

GET /_nodes/stats/jvm?human

告警:

条件 级别
heap used > 85% 持续 5 分钟 warning
old GC 每分钟超过 1 次持续 5 分钟 warning
old GC 单次超过 5 秒 critical
breaker tripped 增加 critical

29.3.3 磁盘

GET /_cat/allocation?v
GET /_nodes/stats/fs?human

关注:

告警:

条件 级别
使用率 > 75% warning
使用率 > 82% critical
按当前增速 7 天内触发 low watermark capacity
IO util > 90% 持续 5 分钟 warning

提前告警比等到 flood stage 更重要。

29.4 索引指标

GET /_stats/indexing,search,merge,refresh,flush,segments?human

29.4.1 写入

指标 含义
indexing.index_total 写入文档数
indexing.index_time 写入耗时
indexing.index_current 当前写入
indexing.index_failed 写入失败
indexing.is_throttled 是否限流
indexing.throttle_time 限流时间

延迟计算:

avg index latency = index_time_in_millis / index_total

29.4.2 查询

指标 含义
search.query_total query phase 次数
search.query_time query phase 总耗时
search.query_current 当前查询数
search.fetch_total fetch phase 次数
search.fetch_time fetch 总耗时
search.scroll_current 当前 scroll
search.suggest_current 当前 suggestion

29.4.3 合并与刷新

关注:

如果 merge throttled time 很高,说明磁盘压力或写入放大已经明显。

29.4.4 Segment

GET /_stats/segments?human

关注:

Segment 数量异常增长通常与 refresh 过频、写入毛刺或 merge 跟不上有关。

29.5 慢查询日志

设置慢查询阈值:

PUT products-v3/_settings
{
  "index.search.slowlog.threshold.query.warn": "3s",
  "index.search.slowlog.threshold.query.info": "1s",
  "index.search.slowlog.threshold.query.debug": "500ms",
  "index.search.slowlog.threshold.fetch.warn": "1s",
  "index.search.slowlog.threshold.fetch.info": "500ms",
  "index.indexing.slowlog.threshold.index.warn": "1s",
  "index.indexing.slowlog.threshold.index.info": "500ms"
}

慢日志应接入日志平台,并至少提取:

注意 info/debug 级别会产生大量日志,生产环境要控制保留时间和磁盘。

29.6 采集链路监控

日志系统还要监控 ES 之前的链路:

组件 指标
应用 输出速率、丢弃数、阻塞队列
Filebeat/OTel registry backlog、发送失败
Kafka lag、分区倾斜、重平衡
消费器 批次耗时、死信数、offset
Pipeline 处理耗时、失败数

如果 Kafka lag 增长但 ES 写入指标下降,问题可能在消费器;如果 ES write rejected 上升,问题可能在集群侧;如果应用无日志,问题可能在应用输出或采集器。

29.7 Prometheus 指标

常用 exporter 会把 Cat API 和 stats API 转为 Prometheus 指标。核心 PromQL 示例:

# cluster status
elasticsearch_cluster_health_status{cluster="prod"}

# node heap
elasticsearch_jvm_memory_used_bytes{area="heap"} / elasticsearch_jvm_memory_max_bytes{area="heap"}

# write rejected
rate(elasticsearch_thread_pool_rejected_count{name="write"}[5m])

# search latency
rate(elasticsearch_indices_search_query_time_seconds[5m]) / rate(elasticsearch_indices_search_query_total[5m])

# disk usage
elasticsearch_filesystem_data_available_bytes / elasticsearch_filesystem_data_size_bytes

Grafana 建议看板:

  1. Cluster Overview:健康、节点数、分片、pending tasks;
  2. Node Health:CPU、heap、GC、磁盘、网络;
  3. Index Throughput:写入 QPS、失败、429;
  4. Search Performance:P95/P99、超时、取消;
  5. Merge & Recovery:merge、refresh、flush、recovery;
  6. Pipeline:Kafka lag、采集失败、死信;
  7. Capacity:磁盘增长、分片大小、节点均衡。

29.8 告警设计

告警要满足:

指标 阈值建议 动作
cluster red 立即 P1,定位分片
node offline 立即 P1,确认机器
disk > 82% 5 分钟 清理或扩容
write rejected 增长 3 分钟 限流、排查
search rejected 增长 3 分钟 查询治理
heap > 85% 5 分钟 排查大查询
breaker 触发 立即 P1
Kafka lag 持续增长 10 分钟 排查消费
快照失败 1 次 检查仓库
master 频繁切换 1 次 P1

29.9 Runbook 模板

每类告警应有标准 Runbook:

告警名称:
严重级别:
业务影响:
确认命令:
常见原因:
止血动作:
升级路径:
恢复标准:
事后动作:

示例:write rejected。

确认:
GET /_cat/thread_pool/write?v
GET /_nodes/stats/indices/indexing,merge?human

止血:
1. 写入端降低并发 50%
2. 开启指数退避
3. 暂停低优先级导入

排查:
1. 查看 rejected 所在节点
2. 查看磁盘水位
3. 查看 merge throttled
4. 查看 bulk item 错误
5. 查看是否有节点离线

恢复标准:
rejected 不再增长,写入 P99 回到基线

29.10 容量预测

容量监控不只看当前使用率,还要看趋势:

剩余天数 = 可用容量 / 最近 7 天日均增长

需要记录:

建议每周发布容量报告:

项目 当前 7 天增长 预计触达水位
磁盘 62% +1.2% 19 天
JVM P95 48% 平稳
写入峰值 8k/s +5% 30 天
查询 P99 800ms +10% 需优化

29.11 监控清单

本章小结

Elasticsearch 监控要同时覆盖集群资源、请求执行、分片状态和上游链路。真正有效的告警不是“CPU 高”,而是能说明影响面、根因方向和处理动作。容量趋势、快照、恢复和慢查询是生产系统最容易被忽视的部分。

思考题

  1. yellow 持续 10 分钟和 red 持续 1 分钟,告警级别如何设计?
  2. 为什么 JVM 告警不能只看瞬时 heap used?
  3. write rejected 上升时,应先检查哪些指标?
  4. 如何计算磁盘预计触达水位时间?
  5. 慢查询日志应该采集哪些上下文字段?