指标采集层设计:数据源分类与采集方式
聊到指标采集层,我脑子里第一个蹦出来的画面,是几年前帮一家电商公司搭监控体系。当时他们服务器都快烧了,可数据就是采不上来。后来一查,好家伙——采集频率设得太高,直接把数据库打挂了。
所以这一章,咱们就好好聊聊采集层该怎么设计。说白了,就是三个问题:采什么、怎么采、采多快。
数据源分类:基础设施、应用、业务
我个人习惯把数据源分成三大类。你想想看,运维要管的东西无非就是这三层:
| 分类 | 典型指标 | 采集难度 | 我踩过的坑 |
|---|---|---|---|
| 基础设施 | CPU、内存、磁盘、网络 | 低 | 磁盘IO等待时间容易被忽略 |
| 应用层 | QPS、响应时间、错误率 | 中 | 线程池耗尽时指标会“假死” |
| 业务层 | 订单量、支付成功率、用户活跃 | 高 | 业务指标和日志时间戳对不上 |
基础设施指标是最容易拿到的。Linux 自带的 /proc 文件系统、SNMP 协议,或者直接用 Prometheus 的 node_exporter,几分钟就能配好。但注意,别只盯着 CPU 使用率。我在项目中遇到过,CPU 看起来才 30%,但系统已经慢得像蜗牛——后来发现是磁盘 IO 在排队。
应用层指标就有点讲究了。你得在代码里埋点,或者用 APM 工具自动注入。我记得有一次,一个 Java 应用的内存指标一直正常,但频繁 Full GC。后来发现是 GC 日志采集频率太低,漏掉了关键信息。嗯,这里要注意:应用层的指标,采样间隔不能大于 GC 停顿时间。
业务层指标是最难搞的。为什么?因为业务数据往往存在数据库里,或者通过消息队列流转。我曾经帮一个支付团队排查问题,发现业务指标显示“支付成功”,但日志里却是“支付失败”。查了半天,原来是业务系统的时间戳和日志系统的时间戳差了 3 秒。你说坑不坑?
采集方式:Agent、API、日志
采集方式就三种,但每种都有它的脾气。
Agent 方式
Agent 是最常见的。在每台机器上装个小程序,让它定期上报数据。Prometheus 的 exporter、Telegraf、Datadog Agent 都是这个路子。
优点很明显:灵活、可控。你想采集什么指标,写个插件就行。但缺点也突出:运维成本高。几百台机器,Agent 版本升级一次,够你忙活一整天。
我曾经吃过一次亏。当时给一个 Kubernetes 集群部署了 200 多个 Pod,每个 Pod 里都跑了一个 Agent。结果 Agent 之间互相抢资源,把宿主机的 CPU 打满了。后来我改成 DaemonSet 方式,一个节点只跑一个 Agent,问题才解决。
API 方式
API 采集适合那些不能装 Agent 的场景。比如云服务商的 RDS、Redis、负载均衡,它们都提供 REST API 让你拉取指标。
但 API 采集有个大坑:限流。我记得有一次,我写了个脚本每 10 秒调一次云厂商的 API,结果半小时后被封了 IP。后来才知道,人家的 API 限制每分钟最多 60 次调用。
所以用 API 方式时,我建议:
- 先看文档,搞清楚 API 的调用限制
- 做好重试和退避策略
- 能批量查询就别单个查
日志方式
日志采集是最“古老”的方式,但也是最灵活的。ELK 栈、Loki、Splunk 都是干这个的。
日志采集的核心是解析。你想想看,原始日志是一堆文本,你得把它变成结构化的指标。比如 Nginx 的 access log,你得从中提取出状态码、响应时间、请求路径。
我习惯用 grok 模式来解析日志。举个例子:
# Nginx 日志格式
log_format main '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent"';
# Grok 解析模式
%{IP:client_ip} - %{USER:ident} \[%{HTTPDATE:timestamp}\]
"%{WORD:method} %{URIPATHPARAM:request} HTTP/%{NUMBER:httpversion}"
%{NUMBER:status} %{NUMBER:bytes}
"%{URI:referrer}" "%{DATA:user_agent}"
解析完就能直接算 QPS、错误率、平均响应时间了。但注意,日志量大的时候,解析本身就会成为瓶颈。我建议在采集端做轻量解析,把原始日志和解析后的指标分开存储。
grep 过滤掉健康检查的请求。这些请求会拉低平均响应时间,让你误以为系统很慢。
采集频率与精度权衡
这是最容易被忽视的问题。很多人觉得“采集频率越高越好”,其实不是。
我画了一张图,帮你理解这个权衡:
你看这张图就明白了。采集频率太低,数据精度不够,你根本看不到系统的真实状态。采集频率太高,资源消耗直线上升,而且精度提升会越来越有限。
那到底怎么设?我给出一个参考值:
| 指标类型 | 推荐采集频率 | 说明 |
|---|---|---|
| CPU/内存 | 10-15秒 | 变化慢,没必要太频繁 |
| 磁盘IO | 5-10秒 | IO波动大,需要稍高频率 |
| 网络流量 | 5-10秒 | 突发流量需要捕捉 |
| 应用QPS | 1-5秒 | 高并发场景建议1秒 |
| 业务订单量 | 30-60秒 | 业务指标变化慢 |
这个表不是绝对的。我建议你根据实际情况调整。比如你的业务有秒杀活动,那 QPS 的采集频率就得提到 1 秒以内。反过来,如果只是日常监控,10 秒一次也够用。
还有一个细节:聚合窗口。比如你每 5 秒采一次 CPU,但展示的时候是按 1 分钟聚合的。那这 1 分钟里的 12 个数据点,你是取平均值还是最大值?
我个人习惯:告警用最大值,报表用平均值。为什么?因为告警要捕捉异常峰值,平均值会平滑掉这些信息。而报表看的是整体趋势,平均值更直观。
好了,这一章的内容就这些。记住三个关键词:分类、方式、权衡。下一章咱们聊聊数据存储层怎么设计,到时候会讲到时序数据库的选择和 schema 设计。
公众号:蓝海资料掘金营,微信deep3321