ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

用Grafana+Infinity拉取Ambari-Metrics指标构建自定义监控面板

用Grafana+Infinity拉取Ambari-Metrics指标构建自定义监控面板 做大数据平台监控的兄弟应该都遇到过这种场景集群用Ambari装完想看指标还得打开Ambari Metrics自带的页面想对比几台机器CPU走势要么来回切Tab要么把数据导出来再加工。更尴尬的是如果你想把HDFS、YARN指标跟业务系统的监控指标放到同一个大屏官方自带模板基本帮不上忙。所以这篇文章我用一个最小可跑的DEMO给你演示怎样用Grafana加Infinity数据源插件把Ambari-Metrics的指标快速拉出来做成自定义监控面板。我会直接给你能照抄的命令、能复现的配置以及我在实际落地时踩过的坑。这个DEMO不需要你懂太多前端或后端按步骤来20分钟之内就能看到第一条CPU曲线出现在Grafana上。如果你正在做大数据平台的统一监控或者要给组里搭一个演示环境这篇内容应该能帮你省不少时间。1. 项目背景与整体思路拆解1.1 为什么放弃Ambari自带图表转投GrafanaAmbari-Metrics是Ambari集群里的监控子系统底层用Metrics Collector接收Agent上报的主机和服务指标默认会保留最近一段时间的数据。Ambari页面里的图表好看是好看但问题也很明显第一它只能展示集群内部指标没法把业务指标、中间件指标拉进同一张图第二Ambari页面本身较重每次加载都要等半天;第三如果你想做二次开发或者把Hadoop集群的指标灌进已有的监控体系官方界面基本是封闭的。Grafana解决的就是“统一展示”的问题。它天生支持大量数据源一个Dashboard里可以同时画MySQL、Prometheus、Elasticsearch的数据也可以画HTTP接口的数据。但Ambari-Metrics没有官方Grafana数据源插件这时候就需要Infinity出场。Infinity是一个通用的Grafana数据源插件它的定位很简单把任意HTTP APIJSON、CSV、GraphQL变成Grafana可以查询的数据表。你只需要给它一个URL、一组请求参数、一段JSONPath它就能把接口返回的数据映射成Grafana的图表数据。1.2 这套组合能解决什么问题我把这个DEMO的目标定得很具体用Grafana Infinity从Ambari-Metrics的REST API里取CPU使用率指标画出一条随时间变化的曲线并且让图表跟随Grafana右上角的时间范围自动变化。这个目标拆解下来就是三件事搞清楚Ambari-Metrics怎么查数据、把查询结果喂给Infinity、在Grafana里配好面板。一旦这条链路通了后面想加内存、磁盘、HDFS容量指标都是复制粘贴的事。这也是我推荐先跑DEMO的原因——技术方案看着复杂但真正上手只需要一条链路。搞定这一条整个监控体系就打通了。1.3 DEMO架构说明整体链路非常短你不需要额外部署组件Ambari Metrics Collector (端口6188) ↓ REST API 查询指标 Grafana Infinity 数据源插件 (读取HTTP JSON) ↓ 传入Grafana时间范围参数 Grafana Dashboard 面板渲染由于Ambari-Metrics返回的数据结构是嵌套的KV对象我在核心环节里加了一个轻量转换层把接口数据压平成Infinity最容易消费的数组格式。这个转换层只有几十行代码是整个DEMO最关键的衔接点。2. 动手前先搞清Ambari-Metrics的取数逻辑2.1 REST API地址和核心参数Ambari-Metrics Collector默认监听在6188端口对外暴露的是Timeline Metrics REST接口。完整路径是http://collector_host:6188/ws/v1/timeline/metrics我用的核心参数有这些参数说明示例值注意事项metricNames要查询的指标名逗号分隔cpu_user,cpu_idle必须与Collector存储的指标名一致appId指标所属应用HOST主机级指标填HOST服务级填HDFS、YARN等hostname主机名不传则返回聚合值node1.example.com留空时返回的是集群聚合后的数据startTime开始时间毫秒时间戳1690000000000Grafana里用${__from}变量自动填充endTime结束时间毫秒时间戳1690003600000Grafana里用${__to}变量自动填充precision返回数据的聚合精度seconds可选days/hours/minutes/seconds需要注意metricNames必须和Ambari Metrics Collector里的指标名完全匹配。如果填错了接口不会报错只是metrics数组为空。这点我后面在踩坑部分会再提。2.2 先用curl验证一下返回结构在Grafana配置之前我强烈建议先用curl在命令行验证一次接口看清楚返回数据的真实结构。命令大概是这样的curl http://ambari-host:6188/ws/v1/timeline/metrics?metricNamescpu_userappIdHOSTstartTime1690000000000endTime1690003600000precisionseconds正常返回的JSON长这样{ metrics: [ { metricname: cpu_user, appid: HOST, hostname: node1.example.com, starttime: 1690000000000, metrics: { 1690000000000: 12.3, 1690000005000: 11.1, 1690000010000: 10.8 } } ] }这个结构就是整个DEMO的难点所在metrics字段是两层嵌套内层的key是时间戳value才是指标值。Grafana的通用数据源没法直接识别这种“动态键值对象”如果强行拿JSONPath去取值你会发现在时间序列面板里看不到任何曲线。2.3 关于precision参数的经验precision参数决定了返回多少个数据点。假如你查的是最近24小时用seconds精度会返回86400个点左右接口压力和数据量都会偏大用minutes精度则只有1440个点画出来的曲线在大部分场景下已经够用了。我的建议是DEMO阶段先用seconds因为数据点密集能明显看到曲线波动。真正生产使用再根据需求调到minutes甚至hours具体细节后面第6章我还会展开说。3. 环境准备Grafana和Infinity插件的安装3.1 快速起一个Grafana实例我这里直接用Docker启动这是最省事的方式。一条命令同时完成Grafana安装和Infinity插件安装docker run -d \ --namegrafana \ -p 3000:3000 \ -e GF_INSTALL_PLUGINSyesore/grafana-infinity-datasource \ grafana/grafana-oss:latest如果你已经装了Grafana也可以用命令行手动装插件grafana-cli plugins install yesore/grafana-infinity-datasource systemctl restart grafana-server装完插件后在Grafana的Connections → Data sources页面看到Infinity数据源类型就算成功了。3.2 在Grafana里添加Infinity数据源进入Data sources页面选择Infinity填配置项。这里有一个容易搞混的点数据源URL应该填什么。如果你的方案是直接连Ambari Metrics CollectorURL就填Collector的地址http://ambari-host:6188如果你和我一样走转换层方案URL就填转换服务地址后面第四部分会写。我建议数据源URL先填Collector地址因为这样面板里的查询路径更直观一眼就能看出请求发到了哪里。3.3 验证数据源连通性Infinity数据源配置页面下方通常有类型测试按钮。在Type里选JSONURL填/ws/v1/timeline/metrics加几个测试参数然后点Test或者Query如果能看到返回的数据说明连接没问题。这一步很重要如果你的Ambari集群启用了安全认证比如Kerberos接口可能会返回401。这个场景比较麻烦需要给Collector配置平级认证或者关闭安全验证我建议DEMO阶段先找一台没有开Kerberos的测试集群。4. 核心DEMO让Grafana画出第一条CPU曲线4.1 方案选择原生解析还是加转换层我在文章开头提到Ambari Metrics返回的嵌套结构对Grafana不友好。实际处理时有两条路方案一全部都在Infinity里解决。新版Infinity支持UQL和较复杂的JSONPath配置理论上可以把嵌套对象展开。但根据我的实测这个方案的配置过程比较折腾不同版本的Infinity对动态key的处理行为也不一样容易在半路卡住。方案二加一个极薄的转换层把接口返回的嵌套结构压平。这样Infinity拿到的就是标准数组JSONPath配置非常简单直接而且后面接其他接口时这套转换逻辑还能复用。这个DEMO我推荐方案二。它听起来多了一步实际上转换层的代码量不超过40行却能大幅降低后面的调试成本。这也是生产环境里常见的做法——各种异构监控API先用一层转换逻辑统一成标准格式再喂给Grafana。4.2 写一个轻量转换服务我用Python Flask写这个转换服务主要是简单、依赖少。代码逻辑就是请求Ambari Metrics接口把嵌套的metrics对象拍平成列表。from flask import Flask, request, jsonify import requests COLLECTOR_HOST http://ambari-host:6188 app Flask(__name__) app.route(/metrics) def metrics(): params { metricNames: request.args.get(metricNames, cpu_user), appId: request.args.get(appId, HOST), startTime: request.args.get(startTime), endTime: request.args.get(endTime), precision: request.args.get(precision, seconds) } hostname request.args.get(hostname) if hostname: params[hostname] hostname resp requests.get(f{COLLECTOR_HOST}/ws/v1/timeline/metrics, paramsparams, timeout10) data resp.json() rows [] for metric in data.get(metrics, []): host metric.get(hostname, all) metric_name metric.get(metricname, ) ts_map metric.get(metrics, {}) for ts, value in ts_map.items(): rows.append({ hostname: host, metricname: metric_name, timestamp: int(ts), value: value }) return jsonify(rows) if __name__ __main__: app.run(host0.0.0.0, port5000)启动方式pip install flask requests python app.py然后验证一下转换结果curl http://localhost:5000/metrics?metricNamescpu_userappIdHOSTstartTime1690000000000endTime1690003600000precisionseconds返回就是标准的扁平行列结构[ { hostname: node1.example.com, metricname: cpu_user, timestamp: 1690000000000, value: 12.3 }, ... ]这个结构里timestamp是毫秒时间戳value是对应值Infinity处理起来非常顺手。4.3 在Grafana中创建面板并配置Infinity查询登录Grafana新建一个Dashboard添加Panel。数据源选择之前配好的Infinity。图表的查询配置按这个来Type选择JSONURL填转换服务的地址并把Grafana自带的模板变量传进去http://localhost:5000/metrics?metricNamescpu_userappIdHOSTstartTime${__from:date:ms}endTime${__to:date:ms}precisionseconds这里${__from:date:ms}和${__to:date:ms}是Grafana内置变量会自动替换成当前面板时间范围对应的毫秒时间戳这样图表就能跟着右上角的时间选择器走了。Fields配置里加三列series字段JSONPath填hostname用于区分不同主机时间字段JSONPath填timestamp类型选Timestamp单位选Milliseconds值字段JSONPath填value类型选Number不同版本的Infinity界面字段名称略有差异但核心就是这三列分组列、时间列、数值列。填完之后点Run Query如果时间范围内有数据下方预览区应该已经出现了表格和曲线。4.4 常见配置误区和检查点我见过最多的问题是字段类型选错。比如把timestamp类型选成Time而不是TimestampGrafana会按指定的时间格式去解析一个毫秒数结果自然全是空值。这里要用Timestamp同时单位勾选Milliseconds。另外如果预览里一片空白先看返回的JSON里rows有没有数据。可以直接在Infinity查询编辑器里看原始响应或者用浏览器打开转换服务的URL。如果rows是空的说明Ambari接口这段就没有数据不是Infinity的问题。画出来之后你会在Grafana面板里看到一条正常的CPU使用率曲线。到这一步核心DEMO已经跑通。5. 扩展与进阶多指标、面板复用和告警接入5.1 一台面板展示多台主机的多个指标DEMO里我们只取了cpu_user实际监控不可能只看一个指标。要扩展也很简单只要在请求URL里把metricNames换成逗号分隔的多个指标名同时给转换服务增加一个逻辑把metricname和hostname合并成一个完整的系列名。比如请求http://localhost:5000/metrics?metricNamescpu_user,cpu_idle,cpu_systemappIdHOSTstartTime${__from:date:ms}endTime${__to:date:ms}precisionseconds返回的每一行里都带metricname字段。此时Infinity的series可以用两个字段组合比如配置一个extra字段叫series_name值为hostname _ metricname也可以直接继续分开配置让Infinity按多字段分组。最终面板里会看到每个指标、每台主机各一条线。如果你只需要聚合值不发hostname参数即可此时转换层会把hostname字段设成all多条metricname就对应多条曲线。5.2 面板拷贝和跨实例复用这次我们用的是整条转换服务链路配置好的面板在Grafana里是通用的。你可以把Dashboard导出成JSON然后复制到另一个Grafana实例里。具体操作是Dashboard设置里选择JSON Model全选复制或者用Export功能下载json文件。这里提一个热词相关的实用技巧如果你要拷贝单个面板而不是整个Dashboard在Panel标题下拉菜单里选Inspect → JSON把面板JSON文件保存好再用Import导入就行。这种方式跨Grafana版本兼容性很好。5.3 接入Alertmanager告警的可行路子Grafana从8.x开始原生Alerting已经比较成熟可以直接在Panel上配阈值告警。数据源如果是Infinity告警引擎同样能拿到查询结果所以你可以给CPU曲线设置一个“大于80%持续5分钟”的规则触发后由Grafana统一发到Alertmanager。如果你想走Alertmanager集中管理可以在Grafana的Alerting里配置Alertmanager数据源把Grafana产生的告警实例投递进去。这一步比较适合已有Alertmanager体系、想统一收口告警通知的团队。需要注意负责发送通知的contact point要提前配置好否则告警只在Grafana界面里看得到邮件、钉钉、企微这些都不会发出去。6. 常见问题与排查技巧实录6.1 时间戳和时区导致图表不对Ambari-Metrics返回的毫秒时间戳是UTC标准时间Grafana面板右上角的时间范围会按照当前用户时区换算。如果发现曲线数据点时间对不上检查两点一是转换层里timestamp字段的类型必须是Timestamp且单位为Milliseconds二是Grafana面板的Timezone设置建议先用默认的Browser Time确认显示正常后再按需要切换。我在DEMO阶段遇到过一次所有曲线整体偏了8小时排查到最后发现不是时间戳解析问题而是面板UTC和浏览器时区设置混用了。记住一点Infinity负责把毫秒时间戳原样传进来时区换算全交给Grafana设置。6.2 接口返回空数据Ambari Metrics Collector默认只保留最近一段时间的指标数据而且会根据配置定期清理。如果查询范围超出了保留期返回内容就是空的metrics数组。遇到这种情况先把面板时间范围缩小到今天再手动调一次接口确认。另外metricNames大小写、appId名称也要核对。Ambari UI里看到的指标名不一定等同于Collector里的存储名最好先用curl接口试一遍。6.3 Infinity JSONPath的调试技巧很多人在Infinity里卡住是因为不知道怎么排查JSONPath配置对不对。我这里给一个实用技巧在Infinity查询编辑器页面配置完URL之后先点击Test或者Query按钮观察返回的DataFrame预览。如果看到[object Object]之类的值说明字段路径指到了某一层对象上没有取到具体数值。这时打开浏览器开发者工具在Network面板里看Infinity请求的原始响应确认数据结构再回头调整JSONPath。还有一个习惯我特别推荐任何时候先确保URL返回的是标准JSON数组再去配Fields。如果原始接口不是数组先让转换层搞定不要在JSONPath里硬刚。6.4 Collector性能和查询频率precision选得越小返回的数据点越多Collector的压力也越大。如果面板开了自动刷新比如5秒一次每次查询都要打Collector接口体量大的集群会明显拖慢页面。生产环境我的建议是面板自动刷新时间不低于1分钟precision按数据的时间跨度动态调整比如近1小时用seconds近24小时用minutes近7天用hours。这样既能看清细节又不会把Collector打挂。6.5 转换层的异常处理转换层是单点如果它挂了Grafana面板会显示No data。我的做法是用systemd守护进程管理这个Python服务或者直接扔进Docker里带--restartalways。再一个就是给转换服务加一个简单的超时控制Ambari接口响应慢的时候不要死等否则Grafana请求会一直转圈。最后再分享一个实际经验。这套组合在我维护的平台里跑了一年多最大的价值不是画面多炫而是把Hadoop集群、业务中间件和云资源的监控全部收敛到了同一个Grafana实例里。Ambari-Metrics只是打通了这个思路的第一步摸清取数链路之后你再接其他HTTP API、写新的转换服务都是同一套打法。如果只是做演示当前这个DEMO完全够用了如果想上生产建议把转换层部署成正式服务再配上告警和权限控制就能成为一套轻量的统一监控入口。
返回列表