Elasticsearch集群监控实战:elasticsearch_exporter+Prometheus+Grafana搭建指南

发布时间:2026/10/12 12:02:02
Elasticsearch集群监控实战:elasticsearch_exporter+Prometheus+Grafana搭建指南 1. 为什么这套监控组合值得你花时间搭Elasticsearch 集群这东西用起来爽出事的时候是真让人抓狂。我见过太多团队ES 集群平时跑得好好的一到业务高峰期就各种慢查询、节点掉线、磁盘写满等到用户反馈搜索卡顿才手忙脚乱去查。问题的根源往往不是 ES 本身不行而是缺少一套能提前预警、能定位瓶颈的监控体系。elasticsearch_exporter Prometheus Grafana这套组合是目前社区里做 ES 集群监控最主流、也最经得起生产环境考验的方案。它的分工很清晰elasticsearch_exporter负责从 ES 的各个接口抓取指标并转换成 Prometheus 能识别的格式Prometheus 负责定时拉取、存储这些时序数据并基于规则触发告警Grafana 则把这些数据渲染成直观的仪表盘让你一眼就能看出集群健不健康。这套方案能解决什么问题简单说它能让你看到集群级别的健康状态绿黄红、节点级别的资源消耗JVM 堆内存、CPU、磁盘、线程池、索引级别的读写性能查询延迟、索引速率、段合并情况以及分片分配是否均衡。适合谁来参考运维工程师、后端开发、SRE以及任何需要对自己维护的 ES 集群负责的人。哪怕你之前没怎么接触过 Prometheus跟着下面的思路走也能把这套东西搭起来。我自己的经验是监控这东西搭建只是第一步真正有价值的是指标选得对不对、告警阈值定得合不合理、出问题时会看哪几个图。所以这篇不会只给你一堆配置文件我会把每个关键指标背后的含义、为什么这么配、踩过哪些坑都讲清楚。2. 整体架构设计与组件选型思路2.1 三个组件各自扮演什么角色先把这三个东西的关系理清楚不然后面配置起来容易懵。elasticsearch_exporter是一个用 Go 写的独立进程它本质上就是个 HTTP 服务。你启动它的时候告诉它 ES 的地址它就会定期去调用 ES 的_cluster/health、_nodes/stats、_stats等接口把返回的 JSON 数据拍平成一堆以elasticsearch_开头的指标暴露在/metrics路径上。Prometheus 来抓这个路径就完成了数据采集。Prometheus 是拉模式pull-based的时序数据库。它按照你配置的scrape_interval定时去抓 exporter 的/metrics把数据存下来。同时它内置了告警规则引擎你可以写 PromQL 表达式当条件满足时触发 Alertmanager 发通知。Grafana 不存数据它只是查询 Prometheus 然后把结果画出来。社区里有现成的 ES 监控 Dashboard 模板导入就能用省去从零画图的时间。2.2 为什么选这套而不是别的市面上监控 ES 的方案不止一种。比如 ES 自带的 X-Pack Monitoring功能确实全但它是商业功能集群规模一大就要收费。再比如用 Metricbeat 采集也能配合 ES 和 Kibana 做监控但如果你已经在用 Prometheus 体系监控其他服务再单独维护一套 Metricbeat ES 存储就有点重复建设了。选elasticsearch_exporter Prometheus Grafana的核心理由有三点。第一统一监控栈。大部分团队已经在用 Prometheus 监控数据库、中间件、应用服务ES 接进来就是加一个 job 的事告警规则、通知渠道都能复用。第二指标可控。exporter 暴露哪些指标、Prometheus 保留多久、Grafana 怎么展示全在你手里不依赖商业授权。第三社区成熟。这个 exporter 在 GitHub 上维护活跃Grafana 官方和社区都有现成的 ES Dashboard遇到问题搜一下基本都有答案。2.3 部署拓扑的两种常见形态实际部署时exporter 放哪里是有讲究的。常见两种做法。一种是集中式部署exporter 单独跑在一台监控机上配置里填 ES 集群的协调节点地址。这种最简单但有个隐患如果 ES 集群开启了安全认证exporter 需要能访问所有节点的 stats 接口网络策略要放开。而且集中式抓取时如果 ES 节点多exporter 串行请求可能比较慢。另一种是边车式sidecar部署在每个 ES 节点上跑一个 exporter只抓本节点的指标。Prometheus 通过服务发现或者静态配置抓取所有 exporter。这种方式压力分散也更符合 Prometheus 的哲学。缺点是部署和维护成本高一些节点扩缩容时要同步调整。我的建议是集群规模在 10 个节点以内用集中式就够了配置简单超过 10 个节点或者对采集实时性要求高考虑边车式。下面实操部分我以集中式为主来讲边车式的差异我会单独提。3. 核心指标解读与采集配置要点3.1 必须关注的几类核心指标exporter 暴露的指标有上百个但真正需要天天盯的其实就那么几类。我把它们分成四组每组说清楚看什么、为什么看。集群健康类elasticsearch_cluster_health_status这个指标最直观0 是绿色、1 是黄色、2 是红色。还有elasticsearch_cluster_health_number_of_nodes、elasticsearch_cluster_health_unassigned_shards。黄色通常意味着有副本分片没分配红色意味着有主分片没分配这两种情况都要立刻查。JVM 与内存类elasticsearch_jvm_memory_used_bytes和elasticsearch_jvm_memory_max_bytes配合看堆内存使用率。ES 对堆内存非常敏感官方建议不超过物理内存的 50%且不要超过 31GB。堆内存持续高于 75% 就要警惕高于 85% 基本离 Full GC 不远了。还有elasticsearch_jvm_gc_collection_seconds_count看 GC 次数和耗时。磁盘与 I/O 类elasticsearch_filesystem_data_used_percent直接反映磁盘使用率。ES 有个水位线机制默认 85% 时不再分配新分片95% 时甚至会把索引设为只读。所以这个指标超过 80% 就该处理了。另外elasticsearch_indices_store_size_bytes看索引占用空间。性能与线程池类elasticsearch_indices_search_query_time_seconds看查询耗时elasticsearch_indices_indexing_index_time_seconds看写入耗时。线程池方面elasticsearch_thread_pool_rejected_count是关键一旦有 rejected说明线程池队列满了请求被拒绝用户体验直接受损。elasticsearch_thread_pool_queue_count看排队情况。3.2 exporter 启动参数怎么配exporter 的启动参数不多但有几个直接影响采集效果。./elasticsearch_exporter \ --es.urihttp://es-coordinating-node:9200 \ --es.all \ --es.indices \ --es.indices_settings \ --es.shards \ --es.snapshots \ --web.listen-address:9114 \ --collector.clustersettings逐个说。--es.uri指定 ES 地址如果有认证就写成http://user:passwordhost:9200。--es.all表示采集所有节点的指标不加的话只采集你指定的那个节点。--es.indices采集索引级别指标这个数据量大如果索引特别多上千个要考虑是否开启否则 exporter 响应会变慢。--es.shards采集分片级别指标对排查分片分配问题很有用。--es.snapshots如果你用快照备份就开。--collector.clustersettings采集集群设置能看到水位线等配置。注意--es.indices和--es.shards在索引数量多的时候会显著增加 exporter 的响应时间和 ES 的查询压力。我遇到过索引超过 2000 个的集群开启这两个采集后 exporter 每次抓取要 10 秒以上Prometheus 默认 10 秒的 scrape_timeout 直接超时。解决办法是调大 timeout或者用--es.indices_regex只采集关心的索引。3.3 Prometheus 抓取配置Prometheus 这边就是加一个 scrape job。scrape_configs: - job_name: elasticsearch scrape_interval: 30s scrape_timeout: 25s static_configs: - targets: [exporter-host:9114] labels: cluster: prod-esscrape_interval设 30 秒比较合适。ES 的指标变化没那么快15 秒有点浪费存储60 秒又可能漏掉短时抖动。scrape_timeout要留足余量因为 exporter 抓取 ES 数据本身要时间设成 interval 的 80% 左右比较稳。labels里加个 cluster 标签多集群场景下在 Grafana 里可以按集群筛选。如果 exporter 是边车式部署用服务发现更合适- job_name: elasticsearch scrape_interval: 30s consul_sd_configs: - server: consul:8500 services: [elasticsearch-exporter]具体用哪种服务发现取决于你的基础设施Kubernetes 环境用kubernetes_sd_configsConsul 环境用consul_sd_configs。4. 从零搭建的完整实操流程4.1 环境准备与 exporter 部署假设你有一台监控服务器上面已经跑着 Prometheus 和 Grafana。现在要把 ES 监控接进来。第一步下载 exporter。去 GitHub releases 页面找对应架构的二进制包或者用 Docker 镜像。生产环境我倾向于用 systemd 管理二进制比 Docker 少一层网络开销排查问题也直接。wget https://github.com/prometheus-community/elasticsearch_exporter/releases/download/v1.7.0/elasticsearch_exporter-1.7.0.linux-amd64.tar.gz tar xzf elasticsearch_exporter-1.7.0.linux-amd64.tar.gz mv elasticsearch_exporter-1.7.0.linux-amd64/elasticsearch_exporter /usr/local/bin/第二步创建 systemd unit。[Unit] DescriptionElasticsearch Exporter Afternetwork.target [Service] Typesimple Userprometheus ExecStart/usr/local/bin/elasticsearch_exporter \ --es.urihttp://10.0.0.10:9200 \ --es.all \ --es.indices \ --es.shards \ --web.listen-address:9114 Restarton-failure RestartSec5 [Install] WantedBymulti-user.target第三步启动并验证。systemctl daemon-reload systemctl enable --now elasticsearch-exporter curl -s http://localhost:9114/metrics | grep elasticsearch_cluster_health_status如果能看到elasticsearch_cluster_health_status{clusteres,colorgreen} 0这样的输出说明 exporter 工作正常。4.2 Prometheus 接入与告警规则exporter 通了之后在 Prometheus 的prometheus.yml里加上前面说的 scrape job然后systemctl reload prometheus。去 Prometheus 的 Web UI 的 Status - Targets 页面应该能看到 elasticsearch 这个 job 是 UP 状态。接下来配告警规则。新建一个es_alerts.ymlgroups: - name: elasticsearch rules: - alert: ESClusterRed expr: elasticsearch_cluster_health_status{colorred} 1 for: 1m labels: severity: critical annotations: summary: ES 集群状态为红色 description: 集群 {{ $labels.cluster }} 存在未分配的主分片请立即排查 - alert: ESClusterYellow expr: elasticsearch_cluster_health_status{coloryellow} 1 for: 5m labels: severity: warning annotations: summary: ES 集群状态为黄色 description: 集群 {{ $labels.cluster }} 存在未分配的副本分片 - alert: ESJVMHeapHigh expr: elasticsearch_jvm_memory_used_bytes{areaheap} / elasticsearch_jvm_memory_max_bytes{areaheap} 0.85 for: 5m labels: severity: warning annotations: summary: ES 节点堆内存使用率过高 description: 节点 {{ $labels.node }} 堆内存使用率超过 85% - alert: ESDiskHigh expr: elasticsearch_filesystem_data_used_percent 80 for: 5m labels: severity: warning annotations: summary: ES 节点磁盘使用率过高 description: 节点 {{ $labels.node }} 磁盘使用率 {{ $value }}% - alert: ESThreadPoolRejected expr: rate(elasticsearch_thread_pool_rejected_count[5m]) 0 for: 2m labels: severity: warning annotations: summary: ES 线程池出现拒绝 description: 节点 {{ $labels.node }} 的 {{ $labels.type }} 线程池出现请求拒绝在prometheus.yml里通过rule_files引入这个文件reload 后告警规则就生效了。实操心得for字段很关键。ES 集群状态偶尔闪一下黄色很正常比如某个节点重启期间。如果for设成 0你会被大量瞬时告警淹没。我一般给红色设 1 分钟黄色设 5 分钟堆内存和磁盘设 5 分钟线程池拒绝设 2 分钟。这个节奏既能及时发现问题又不会太吵。4.3 Grafana Dashboard 导入与定制Grafana 这边最省事的做法是导入现成模板。Grafana 官网 Dashboard 库里搜 Elasticsearch有几个高星模板比如 ID 为 2322 的那个覆盖了集群概览、节点详情、索引性能等面板。导入步骤Grafana 左侧菜单 - Dashboards - Import - 输入模板 ID - 选择 Prometheus 数据源 - Import。导入后你会发现有些面板没数据通常是两个原因。一是模板里的指标名和你的 exporter 版本对不上新版本 exporter 改过一些指标名。二是变量比如$node、$index的查询语句需要根据你的标签调整。这时候就要手动改面板的查询。我一般会基于模板做几处定制。把集群健康状态做成 Stat 面板绿色/黄色/红色直接对应颜色一眼就能看。把 JVM 堆内存使用率做成 Gauge阈值设在 75% 和 85%。把线程池 rejected 做成 Time series按节点和线程池类型分组。再单独加一个磁盘使用率的表格按使用率降序排列方便快速定位快满的节点。4.4 关键面板的 PromQL 写法模板里的 PromQL 不一定符合你的需求这里给几个我常用的。集群健康状态elasticsearch_cluster_health_status{colorgreen} 1堆内存使用率elasticsearch_jvm_memory_used_bytes{areaheap} / elasticsearch_jvm_memory_max_bytes{areaheap} * 100查询速率每秒查询次数rate(elasticsearch_indices_search_query_total[5m])查询平均延迟毫秒rate(elasticsearch_indices_search_query_time_seconds[5m]) / rate(elasticsearch_indices_search_query_total[5m]) * 1000索引速率每秒写入文档数rate(elasticsearch_indices_indexing_index_total[5m])线程池队列积压elasticsearch_thread_pool_queue_count这些 PromQL 你可以直接贴到 Grafana 面板的查询框里改一下图例和单位就能用。5. 常见问题排查与避坑经验5.1 exporter 抓取超时或指标缺失这是最常见的问题。表现是 Prometheus 里这个 target 时好时坏或者 exporter 的/metrics响应特别慢。原因通常有三个。一是 ES 集群索引太多--es.indices采集开销大。解决办法是用--es.indices_regex限制采集范围比如只采集业务索引。二是 exporter 到 ES 的网络延迟高或者 ES 本身负载高响应慢。可以在 exporter 所在机器上curl -w %{time_total}测一下 ES 接口的响应时间。三是 exporter 单进程串行请求所有节点节点多的时候慢。这种情况考虑边车式部署。排查时先看 exporter 日志加--log.leveldebug能看到每次请求的耗时。然后看 Prometheus 的 target 页面scrape duration 是多少。如果接近 scrape_timeout就要优化了。5.2 指标名对不上导致面板空白exporter 版本升级时改过指标名比如早期版本用elasticsearch_jvm_memory_used_bytes某些版本可能加了前缀或改了后缀。Grafana 模板是基于特定版本做的版本不匹配就空白。解决办法是先去 Prometheus 里查一下实际有哪些指标。在 Prometheus Web UI 的 Graph 页面输入{__name__~elasticsearch_.*}就能看到所有 ES 相关指标名。然后对照着改 Grafana 面板的查询。5.3 告警风暴怎么治刚上线监控时最容易出这个问题。集群状态一抖、某个节点 GC 一下告警就刷屏。治标的方法是调for时长和阈值。治本的方法是做告警分组和抑制。在 Alertmanager 里配置group_by: [alertname, cluster]把同类告警合并。再配inhibit_rules比如集群红色告警触发时抑制该集群下所有节点级别的告警因为根因已经找到了。还有一个技巧是给告警加severity标签critical 的发短信或电话warning 的只发群消息。这样既不会漏掉严重问题又不会被 warning 吵到。5.4 磁盘水位线告警的坑ES 默认磁盘水位线是 85% 和 95%。但如果你在 ES 里改过cluster.routing.allocation.disk.watermark配置告警阈值就要跟着改。我见过一个案例运维把水位线调到了 90%但告警还设在 80%结果天天告警但没人处理最后真到 95% 时反而没人注意了。所以告警阈值一定要和 ES 实际配置对齐。可以用--collector.clustersettings采集集群设置然后在 Grafana 里把水位线配置和实际磁盘使用率画在一起这样一眼就能看出离水位线还有多远。5.5 常见问题速查表现象可能原因排查方向解决思路target 频繁 downexporter 进程崩溃或超时看 exporter 日志和 systemd 状态调大 scrape_timeout检查 ES 响应指标缺失采集开关没开或版本不匹配查/metrics实际输出加对应--es.xxx参数面板空白指标名或标签对不上Prometheus 里查实际指标改 Grafana 查询语句告警刷屏阈值太敏感或 for 太短看告警历史调阈值、加 for、配抑制规则堆内存告警但 GC 正常堆内存高但没到 GC 压力看 GC 次数和耗时结合 GC 指标判断避免误报磁盘告警但 ES 没反应告警阈值低于 ES 水位线对比 ES 配置对齐告警阈值和 ES 水位线6. 监控体系持续优化的几个方向搭起来只是开始真正让监控产生价值的是持续调优。我分享几个自己实践下来觉得有用的方向。指标分层。把指标分成必须告警、需要关注、仅作参考三层。必须告警的比如集群红色、磁盘超水位线、线程池拒绝需要关注的比如堆内存、查询延迟仅作参考的比如段数量、合并次数。Grafana 首页只放第一层和第二层第三层放到详情页。这样值班的人一眼就能看到关键信息。容量趋势预测。用 Prometheus 的predict_linear函数做磁盘容量预测。比如predict_linear(elasticsearch_filesystem_data_used_percent[7d], 86400*30)能预测 30 天后的磁盘使用率。如果预测值超过 85%就提前扩容或清理索引而不是等告警响了才动手。慢查询关联分析。把 ES 的慢查询日志和监控指标关联起来。当查询延迟告警触发时能快速定位是哪个索引、哪类查询导致的。这个需要在应用层埋点或者开启 ES 的慢查询日志然后把日志和监控面板联动。定期回顾告警。每个月花半小时看看这个月触发了哪些告警、哪些是误报、哪些阈值需要调整。监控不是配完就不管了它需要跟着业务变化一起演进。我个人在实际操作中的体会是监控体系的价值不在于图有多好看、指标有多全而在于出问题时你能不能快速定位、平时能不能提前发现隐患。我见过指标采集了几百个但没人看的集群也见过只盯十几个关键指标但每次都能提前预警的集群。后者才是我们该追求的状态。所以别贪多先把集群健康、JVM、磁盘、线程池这四类核心指标盯住告警阈值调准再慢慢扩展。这套elasticsearch_exporter Prometheus Grafana的组合只要你把核心指标和告警规则打磨好它能陪你走很远。

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询