资讯动态

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

发布时间:2026/10/12 22:09:57 来源:尧图企业网站定制
1. 为什么这套监控组合值得你花时间搭Elasticsearch 集群跑起来容易跑稳很难。我见过太多团队在业务量上来之后集群突然变慢、查询超时、节点掉线而运维同学只能靠_cat/health和_cat/nodes手动敲命令去猜问题出在哪。这种盲人摸象式的排查一次两次还行真到了生产环境出故障根本来不及。elasticsearch_exporter Prometheus Grafana这套组合本质上解决的就是把 ES 集群的黑盒变成白盒这件事。elasticsearch_exporter 负责从 ES 的各类 API 里抓取指标并转换成 Prometheus 能识别的格式Prometheus 负责定时拉取和存储这些时序数据Grafana 则把这些数据渲染成直观的仪表盘。三者各司其职形成一条完整的采集—存储—可视化链路。这套方案适合谁如果你是负责维护 ES 集群的运维或后端开发手头集群规模在几个节点到几十个节点之间又不想上那些重量级的商业监控平台那这套组合基本是最优解。它足够轻量部署成本低社区生态成熟而且所有组件都是开源的不用担心授权问题。哪怕你只有一台 ES 节点搭一套起来也能帮你提前发现磁盘水位、JVM 压力、查询延迟这些隐患。我个人的经验是ES 集群的故障有相当一部分是有前兆的——磁盘快满了、GC 时间变长了、线程池开始排队了。这些信号如果没人盯着等到用户报障时往往已经晚了。监控的价值不在于出事之后能看回放而在于出事之前能收到告警。接下来我会把这套方案的选型逻辑、部署细节、指标解读和踩坑经验完整拆一遍你照着做基本能复现出一套可用的监控体系。2. 方案整体设计与选型思路拆解2.1 三个组件各自扮演什么角色先把分工说清楚不然后面配置容易懵。elasticsearch_exporter是一个用 Go 写的独立进程它定期调用 ES 的_cluster/health、_nodes/stats、_cluster/stats、_stats等接口把返回的 JSON 数据转换成 Prometheus 的指标格式然后暴露在自己的/metrics端点上。它本身不存储数据只做翻译工作。你可以把它理解成一个适配器把 ES 说的话翻译成 Prometheus 听得懂的话。Prometheus是时序数据库加采集器。它按照配置的时间间隔主动去 exporter 的/metrics端点拉数据注意是 Prometheus 主动拉不是 exporter 推然后把带时间戳的指标存到自己的 TSDB 里。它还负责根据你写的告警规则去评估指标触发告警。Grafana是可视化层。它从 Prometheus 查询数据用图表展示出来。Grafana 本身不存数据它只是个画图工具数据源指向 Prometheus 就行。2.2 为什么不用 ES 自带的监控ES 从 7.x 开始自带了 Stack Monitoring功能确实不错但有几个现实问题。第一它通常需要配合 Kibana 使用而 Kibana 本身也是个吃资源的组件为了看监控再单独维护一套 Kibana 有点重。第二Stack Monitoring 的数据保留策略和告警能力相对有限想做一些自定义的告警规则比较别扭。第三如果你的技术栈里已经有 Prometheus 和 Grafana 在监控其他服务再单独为 ES 维护一套监控体系运维心智负担会翻倍。用 Prometheus 体系的好处是统一。数据库、中间件、应用服务的指标全在一个地方告警规则用同一套 PromQL 写Grafana 上可以做一个总览大盘把所有服务串起来看。这种统一性在故障排查时特别有价值——你能在一个时间轴上看到 ES 变慢的同时上游应用的请求量是不是也在涨。2.3 采集频率和保留周期的权衡这是很多人一开始会忽略的点。Prometheus 的scrape_interval决定了多久拉一次数据。设太短比如 5 秒指标量大、存储压力大设太长比如 5 分钟故障的细节就看不到了。我的建议是 ES 集群监控用15 秒到 30 秒的采集间隔。ES 的很多指标比如 GC、线程池队列变化是以秒为单位的15 秒能捕捉到大部分异常波动同时数据量也可控。如果集群节点特别多比如超过 50 个可以适当放宽到 30 秒。保留周期方面Prometheus 默认保留 15 天。对于 ES 监控我一般会设到30 天因为有些问题比如磁盘缓慢增长、慢查询逐渐增多需要看更长时间的趋势才能发现。存储空间估算的话一个中等规模集群10 节点左右30 天的数据大概占用几十 GB具体取决于指标数量和采集频率。2.4 部署形态的选择exporter 的部署位置有讲究。它需要能访问 ES 的 HTTP 接口所以放在能连通 ES 的机器上就行。常见做法有两种一是跟 ES 节点部署在一起每个节点一个 exporter二是单独找一台机器部署一个 exporter 监控整个集群。这里有个关键区别节点级指标比如某个节点的 JVM 堆内存、磁盘使用率需要 exporter 能访问到具体节点的 stats 接口。如果你只部署一个 exporter它通过_nodes/stats能拿到所有节点的数据但 Prometheus 抓取时所有节点指标会混在一起需要用instance或node标签区分。而每个节点部署一个 exporter 的话指标天然按实例分开更清晰但部署和维护成本高一些。我个人的选择是中小集群用一个 exporter 集中采集配置简单够用大集群或者对节点级指标要求精细的场景用 DaemonSet 方式每个节点一个 exporter。下面实操部分我会以集中采集为主来讲因为这是最容易上手的。3. 核心细节解析与实操要点3.1 elasticsearch_exporter 的安装与关键参数exporter 的安装很简单官方提供二进制包和 Docker 镜像。我以二进制方式为例因为这样你能清楚看到每个参数的作用。下载对应平台的二进制包后直接运行./elasticsearch_exporter \ --es.urihttp://es-node-1:9200 \ --es.all \ --es.indices \ --es.indices_settings \ --es.shards \ --es.snapshots \ --web.listen-address:9114这里几个参数值得展开说--es.uri指定 ES 的地址。如果集群有多个节点填任意一个可用的就行exporter 会通过这个节点去获取整个集群的信息。如果 ES 开了认证格式是http://user:passwordhost:9200。--es.all表示采集所有节点的指标。不加这个参数的话默认只采集你指定的那个节点的数据。对于集群监控来说这个参数基本是必加的。--es.indices、--es.indices_settings、--es.shards这几个是采集索引级别的指标。这里有个坑要注意如果你的集群索引特别多比如上千个开启这些参数会导致 exporter 采集变慢甚至给 ES 带来额外压力。索引数量多的时候建议只开--es.indices或者干脆不开索引级指标只监控集群和节点级别。--web.listen-address是 exporter 自己暴露指标的端口默认 9114。提示exporter 启动后先用curl http://localhost:9114/metrics确认能拿到数据再去配 Prometheus。这一步能帮你排除掉一大半连接和认证问题。3.2 Prometheus 抓取配置的写法Prometheus 的配置文件里加一个 job 就行scrape_configs: - job_name: elasticsearch scrape_interval: 15s scrape_timeout: 10s static_configs: - targets: [exporter-host:9114] labels: cluster: prod-esscrape_timeout要小于scrape_interval一般设成间隔的三分之二左右。如果 exporter 采集慢索引多的时候会超时时间要适当放宽否则会出现大量抓取失败。labels里的cluster标签很有用。如果你监控多个 ES 集群用这个标签区分Grafana 里可以做变量筛选。3.3 指标分类与重点关注项exporter 暴露的指标有几百个全看会眼花。我按重要性给你分个类重点盯这几组就够了。集群健康类指标名含义关注点elasticsearch_cluster_health_status集群状态0green, 1yellow, 2redelasticsearch_cluster_health_number_of_nodes节点数突然减少说明有节点掉线elasticsearch_cluster_health_unassigned_shards未分配分片大于 0 要警惕elasticsearch_cluster_health_active_shards活跃分片数结合总量看节点资源类指标名含义关注点elasticsearch_jvm_memory_used_bytesJVM 内存使用堆内存持续高位要警惕elasticsearch_jvm_gc_collection_seconds_countGC 次数频繁 GC 是性能杀手elasticsearch_filesystem_data_used_percent磁盘使用率超过 85% 必须处理elasticsearch_process_cpu_percentCPU 使用率持续高说明负载重性能类指标名含义关注点elasticsearch_indices_search_query_time_seconds查询耗时突增说明查询变慢elasticsearch_indices_indexing_index_time_seconds索引耗时写入性能指标elasticsearch_thread_pool_queue_count线程池队列大于 0 说明有排队这几组指标覆盖了 ES 集群 80% 的常见问题。剩下的分片、快照、段合并等指标等你有具体需求时再深入看。3.4 Grafana 数据源与大盘准备Grafana 里先加 Prometheus 数据源地址填 Prometheus 的地址保存后测试一下连通性。大盘方面Grafana 官方社区有现成的 ES 监控模板导入就能用。但我建议你不要直接拿来就用而是先理解每个面板在画什么然后根据自己的集群特点调整。现成模板的问题在于它可能包含一些你用不到的指标或者缺少你特别关心的指标。导入模板的步骤在 Grafana 里点 Dashboards → Import把模板 ID 或 JSON 贴进去选择数据源导入即可。常用的 ES 监控模板在 Grafana 官网能搜到选下载量高、更新近的。4. 实操过程与核心环节实现4.1 环境准备与连通性验证假设你有一台监控服务器叫它 monitor-host能访问 ES 集群。先在 monitor-host 上验证网络连通curl -s http://es-node-1:9200/_cluster/health?pretty能返回 JSON 就说明网络和 ES 都正常。如果 ES 开了认证加上-u user:password。这一步别跳过。我遇到过好几次exporter 配好了但拿不到数据最后发现是防火墙没放行或者认证信息写错了。提前验证能省很多时间。4.2 部署 exporter 并验证指标输出把 exporter 二进制放到 monitor-host 上用 systemd 管理起来这样开机自启、崩溃自动重启。创建/etc/systemd/system/es-exporter.service[Unit] DescriptionElasticsearch Exporter Afternetwork.target [Service] Usermonitor ExecStart/opt/es-exporter/elasticsearch_exporter \ --es.urihttp://es-node-1:9200 \ --es.all \ --es.indices \ --web.listen-address:9114 Restartalways RestartSec10 [Install] WantedBymulti-user.target启动并验证systemctl daemon-reload systemctl start es-exporter systemctl enable es-exporter curl -s http://localhost:9114/metrics | grep elasticsearch_cluster_health_status看到类似elasticsearch_cluster_health_status{colorgreen,clusteres} 0的输出就说明 exporter 工作正常了。4.3 Prometheus 配置与热加载在 Prometheus 的prometheus.yml里加上前面说的 job 配置然后热加载curl -X POST http://localhost:9090/-/reload热加载需要 Prometheus 启动时带了--web.enable-lifecycle参数。如果没有就重启 Prometheus。加载后去 Prometheus 的 Web UI默认 9090 端口在 Status → Targets 里看 elasticsearch 这个 job 的状态。State 显示 UP 就说明抓取成功。如果显示 DOWN点进去看错误信息通常是连接超时或认证失败。4.4 告警规则配置监控不配告警等于白搭。在 Prometheus 里加告警规则文件比如es-alerts.ymlgroups: - name: elasticsearch rules: - alert: ESClusterRed expr: elasticsearch_cluster_health_status{colorred} 1 for: 1m labels: severity: critical annotations: summary: ES 集群状态为 RED description: 集群 {{ $labels.cluster }} 处于 RED 状态存在主分片未分配 - alert: ESDiskHigh expr: elasticsearch_filesystem_data_used_percent 85 for: 5m labels: severity: warning annotations: summary: ES 节点磁盘使用率过高 description: 节点 {{ $labels.node }} 磁盘使用率 {{ $value }}% - alert: ESJVMHeapHigh expr: elasticsearch_jvm_memory_used_bytes{areaheap} / elasticsearch_jvm_memory_max_bytes{areaheap} 0.85 for: 10m labels: severity: warning annotations: summary: ES JVM 堆内存使用率过高for参数表示条件持续多久才触发告警避免瞬时抖动误报。集群 RED 这种严重问题设 1 分钟磁盘和内存这种可以设 5 到 10 分钟。告警的接收端可以接 Alertmanager再转发到邮件、企业微信、钉钉等。这部分配置比较独立按 Alertmanager 官方文档配就行。4.5 Grafana 大盘搭建与面板设计导入模板后我建议至少保留和调整这几个核心面板集群健康总览用 Stat 面板显示集群状态、节点数、未分配分片数。状态用颜色映射green 绿色、yellow 黄色、red 红色一眼就能看出问题。节点资源趋势用 Time series 面板画各节点的 CPU、内存、磁盘使用率。磁盘那条线设个 85% 的阈值线接近了就警觉。JVM 与 GC堆内存使用率和 GC 次数放一起看。GC 次数曲线突然变陡往往意味着内存压力大。查询与写入性能查询耗时、索引耗时的 P95/P99 分位数。平均值会掩盖长尾问题分位数更能反映真实体验。线程池队列队列数大于 0 的持续时间是判断集群是否过载的重要信号。面板的刷新间隔设成 30 秒到 1 分钟就行太频繁没必要还增加 Prometheus 查询压力。5. 常见问题与排查技巧实录5.1 exporter 拿不到数据怎么办这是最常见的问题。排查顺序我一般是这样先确认 exporter 进程活着systemctl status es-exporter。再看 exporter 日志journalctl -u es-exporter -n 50。日志里通常会直接告诉你连不上还是认证失败。如果日志没线索手动模拟 exporter 的请求curl -u user:pass http://es-node-1:9200/_cluster/health。这一步能确认是 ES 侧的问题还是 exporter 配置的问题。还有一种情况是 ES 响应慢导致 exporter 超时。索引特别多的时候_stats接口可能要好几秒才返回。解决办法是减少采集项或者调大 exporter 的超时参数。5.2 Prometheus 显示 target DOWNTarget DOWN 的原因无非几种网络不通、端口不对、exporter 没起来、超时。先在 Prometheus 所在机器上curl http://exporter-host:9114/metrics能通说明网络没问题。然后看 Prometheus 的报错信息它会明确写是 connection refused 还是 timeout。如果是 timeout把scrape_timeout调大。如果是 connection refused检查 exporter 监听地址是不是0.0.0.0而不是127.0.0.1。我踩过这个坑exporter 默认监听所有地址但有些配置会限制成 localhost导致远程拉不到。5.3 指标缺失或不完整有时候 target 是 UP 的但某些指标查不到。这通常是 exporter 启动参数没开对应的采集项。比如你没加--es.indices那索引级指标就不会有。对照 exporter 的启动参数和你想看的指标确认采集项都开了。另外ES 版本不同某些指标的命名或存在性会有差异遇到查不到的指标先去 exporter 的/metrics输出里搜一下确认它到底有没有。5.4 告警误报和漏报误报多半是阈值设得太敏感或者for时间太短。比如磁盘使用率业务高峰期短暂冲到 86% 很正常如果for只设 1 分钟就会频繁告警。把for拉长到 5 到 10 分钟能过滤掉大部分抖动。漏报则要检查告警规则的表达式对不对。PromQL 写错了不会报错只是永远不触发。写完规则后去 Prometheus 的 Alerts 页面看规则状态确认表达式能正确评估出结果。5.5 常见问题速查表现象可能原因排查方向exporter 无输出连不上 ES / 认证失败看 exporter 日志手动 curl EStarget DOWN网络 / 端口 / 超时从 Prometheus 机器 curl exporter指标缺失采集参数未开对照启动参数检查告警不触发PromQL 写错在 Prometheus 里手动执行表达式告警频繁误报阈值敏感 / for 太短调整阈值和持续时间Grafana 无数据数据源配置错测试数据源连通性5.6 几个我踩过的坑坑一exporter 版本和 ES 版本不匹配。ES 大版本升级后某些 API 的返回结构会变老版本 exporter 可能解析失败。升级 ES 时记得同步看下 exporter 有没有新版本。坑二索引太多拖垮 exporter。前面提过上千个索引时开索引级采集会让 exporter 很吃力。这种场景建议用--es.indices配合过滤或者干脆只监控集群和节点级别。坑三Prometheus 存储爆盘。采集频率高、指标多、保留周期长三者叠加很容易把磁盘写满。定期看下 Prometheus 的数据目录大小必要时调整保留周期或做降采样。坑四Grafana 大盘查询太慢。面板里用了高基数high cardinality的标签做分组查询会非常慢。比如按索引名分组画图索引一多就卡。这种情况要么减少分组维度要么用 recording rule 预聚合。6. 指标解读与容量规划经验6.1 从指标看集群健康度光有数据不会看也白搭。我总结几个判断集群健康的经验值。JVM 堆内存使用率长期超过 75%说明堆可能不够用GC 压力会越来越大。ES 官方建议堆不超过物理内存的 50%且不超过 32GB。如果你的堆使用率一直高位先看是不是堆设小了再看是不是有内存泄漏或查询太耗内存。GC 老年代回收时间占比超过 5%就要警惕了。可以用elasticsearch_jvm_gc_collection_seconds_sum除以采集周期估算。GC 时间占比高查询延迟必然受影响。线程池队列持续大于 0说明请求处理不过来。search 队列和 write 队列要分开看。search 队列堆积通常是查询太慢或并发太高write 队列堆积则是写入压力大。磁盘使用率超过 85%ES 会自动把分片迁走甚至设成只读。这个阈值一定要提前告警别等到 ES 自己动手。6.2 容量规划的基本思路监控数据反过来能指导容量规划。比如你观察到磁盘使用率每月增长 5%那大概 3 个月后就会到 85% 的警戒线需要提前扩容或清理数据。节点数方面如果 CPU 和内存长期高位说明单节点扛不住了该加节点。加节点后分片会重新平衡短期内指标会有波动这是正常的。分片数量也是个容易出问题的地方。分片太多会增加集群管理开销太少又影响并行度。一般建议单个分片大小控制在 10GB 到 50GB 之间。监控里的分片相关指标能帮你判断当前分片策略是否合理。6.3 监控体系的持续维护监控搭好不是一劳永逸。ES 版本升级、集群扩容、业务变化都会让原来的阈值和面板不再适用。我习惯每个季度回顾一次告警规则看看哪些告警从来没触发过可能阈值太松哪些频繁误报可能太紧。Grafana 大盘也是业务变了关注的面板也要跟着调整。另外exporter、Prometheus、Grafana 这些组件本身也要监控。Prometheus 自己挂了整个监控体系就瞎了。可以用一个独立的轻量监控盯着 Prometheus 的存活和存储状态形成监控的监控。这套组合我用了几年从几个节点的小集群到几十个节点的生产集群都跑过稳定性没得说。真正花时间的不是搭建而是根据自己集群的特点去调阈值、调面板、积累对指标的理解。搭起来只是第一步用起来、用明白才是这套监控体系真正的价值所在。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑