指标采集层设计:数据源分类与采集方式

聊到指标采集层,我脑子里第一个蹦出来的画面,是几年前帮一家电商公司搭监控体系。当时他们服务器都快烧了,可数据就是采不上来。后来一查,好家伙——采集频率设得太高,直接把数据库打挂了。

所以这一章,咱们就好好聊聊采集层该怎么设计。说白了,就是三个问题:采什么、怎么采、采多快

数据源分类:基础设施、应用、业务

我个人习惯把数据源分成三大类。你想想看,运维要管的东西无非就是这三层:

分类 典型指标 采集难度 我踩过的坑
基础设施 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,问题才解决。

避坑指南:Agent 采集时,一定要设置资源限制。我曾经见过 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 秒一次也够用。

我的经验:先设一个保守的频率(比如 15 秒),运行一周后看数据质量。如果发现漏掉了关键波动,再逐步提高频率。别一上来就设 1 秒,除非你资源多到用不完。

还有一个细节:聚合窗口。比如你每 5 秒采一次 CPU,但展示的时候是按 1 分钟聚合的。那这 1 分钟里的 12 个数据点,你是取平均值还是最大值?

我个人习惯:告警用最大值,报表用平均值。为什么?因为告警要捕捉异常峰值,平均值会平滑掉这些信息。而报表看的是整体趋势,平均值更直观。

注意:采集频率和存储成本直接挂钩。每 5 秒采一次,一天就是 17280 个数据点。1000 个指标,一年就是 6.3 亿条数据。存储和查询都会成为问题。所以一定要做降采样和数据保留策略。

好了,这一章的内容就这些。记住三个关键词:分类、方式、权衡。下一章咱们聊聊数据存储层怎么设计,到时候会讲到时序数据库的选择和 schema 设计。


公众号:蓝海资料掘金营,微信deep3321