硬件资源监控这件事,说它简单也简单,无非是把 CPU、内存、磁盘、网络这些数抓出来存起来画成图;说它难也难,难在你抓了半年之后发现,真正出事的那次,图表上什么都看不出来。我自己先后在几套不同规模的机器集群上搭过监控,从最初只有三台开发机的小环境,到后来几百台混布节点的机房,中间踩的坑基本都集中在“指标选错”和“阈值定歪”这两件事上。这篇就把硬件资源监控从指标定义、采集落地、存储计算到告警调优的完整链路拆一遍,重点讲那些文档里通常不写、但实际会卡住你的地方。不管你是刚接手一批服务器、想给机房补一套基础监控,还是已经在用现成方案但告警天天响、没人看,下面这些内容应该都能直接拿去用。
1. 先想清楚硬件资源监控到底在盯什么
1.1 三个真实踩过的场景
先说三个我印象比较深的场景,它们基本决定了硬件资源监控的边界在哪里。
第一个场景是某台跑离线计算的机器,业务方反馈任务跑得越来越慢,登录上去看 CPU 使用率只有 30% 出头,一切正常。后来翻历史曲线才发现,这块盘的 IO 等待时间长期在 200ms 以上,CPU 的 wa(IO 等待)占了 40%,但因为我们当时只盯着“CPU 使用率不超过 80%”这一条,压根没看 wa 这个细分项,问题拖了小半个月。这件事之后我把 CPU 指标拆成了 us、sy、wa、st 四项分开看,单项告警比总量告警有用得多。
第二个场景更典型。某台机器磁盘使用率 78%,离我们设的 85% 告警线还远,结果应用疯狂报“No space left on device”。查了半天是 inode 用满了——那台机器上跑的是一个会生成海量小文件的同步任务,每个文件几 KB,块设备还有大量空闲空间,但 inode 早就见底了。容量和 inode 是两个完全独立的维度,只监控其中一个等于监控了一半。
第三个场景是硬件层面的。某台机器的内存错误纠正计数在几个月里悄悄往上涨,操作系统层面完全无感,业务也正常跑,直到某天内存条彻底失效导致整机宕机。这类信息只存在于带外管理口(也就是常说的 BMC/IPMI 那一套)里,操作系统内部的所有采集脚本都拿不到。
把这三个场景放在一起看就很清楚了:硬件资源监控要覆盖的,是“操作系统视角的软件指标”加“硬件自身暴露的健康指标”两层,缺一层都会留下盲区。
1.2 把指标分成四层,选型就不会乱
我在实际项目里习惯把所有指标分成四层,这个分层方式对后面定采集频率、定保留周期、定告警策略都很有帮助。
第一层是基础用量层,回答“还剩多少”的问题:CPU 使用率、内存可用量、磁盘剩余容量与 inode、带宽占用。这一层的特点是变化缓慢、对精度要求不高,采集间隔拉到 60 秒甚至 5 分钟都够用,存储成本最低,保留时间可以拉到一年以上,主要是给容量规划看趋势。
第二层是压力层,回答“现在忙不忙、堵不堵”的问题:CPU 的运行队列长度、内存的换页速率、磁盘的 IO 队列深度和平均等待时间、网卡的丢包与重传。这一层变化快,必须用 10 到 15 秒的间隔采,否则尖峰全被抹平了。这一层也是排查性能问题的主要依据。
第三层是健康层,回答“硬件有没有毛病”的问题:温度、风扇转速、电源状态、磁盘的 SMART 属性、内存的纠错计数、网卡的物理层错误计数。这一层变化极慢,但一旦有变化就是大事,采集间隔可以放到 5 分钟,但必须保证“不丢点”,而且阈值判断要看趋势而不是瞬时值。
第四层是趋势层,回答“按这个速度还能撑多久”的问题:磁盘每日增量、内存水位周环比、带宽的月度峰值分布。这一层不是原始采集出来的,是从前三层数据里按天做聚合算出来的,通常放在离线任务里跑,结果写回一张独立的表。
分成这四层之后最大的好处是,你不会再纠结“到底 15 秒采一次还是 60 秒采一次”这种问题——不同层用不同频率就行,混在一起采才是真的浪费。我曾经见过一套方案为了省事,把所有指标统一按 5 秒采集,结果存储半年就撑不住了,只能忍痛删历史数据,而删掉的那部分恰好是容量规划最需要的长周期趋势。
1.3 采集精度的成本,得先算清楚
在动手之前,有一个数必须先估出来:你的时间序列总量。这个数直接决定了存储要多大、采集端要多少资源、查询会不会卡。
估算方法不复杂:先把机器数量乘上每台机器的活跃指标数,得到时间序列条数;再除以采集间隔,得到每秒写入的点数。举个具体的例子,200 台机器,每台采 800 个指标项,采集间隔 15 秒,那么时间序列是 16 万条,每秒写入点数是 200 × 800 ÷ 15 ≈ 10667 点/秒。
接下来是存储。现代时序数据库对这个量级的压缩比通常在每点 1 到 2 字节之间,取 1.5 字节估算:10667 × 1.5 ≈ 16 KB/秒,一天约 1.4 GB,一个月约 42 GB。如果换成不做列压缩的通用数据库,每点按 16 字节算,一天就是 14.7 GB,一个月 440 GB,差了十倍。这个对比不是为了说哪个数据库好,而是想说:存储成本的估算必须在选型之前做,而不是之后。
注意:上面的 800 个指标项对一台普通业务机来说不算夸张——光是各块磁盘的分区容量、inode、读写延迟、队列深度,再加上每张网卡的收发字节、包数、错误数、丢弃数,很容易就过百。如果机器上还跑了容器,指标数翻两三倍是常态。做估算时宁可往大了算。
2. 指标体系的搭建:先定指标,再挑工具
2.1 CPU:使用率几乎是最没用的那个数
CPU 使用率之所以没用,是因为它是一个被平均过的数。8 核机器上一个核跑满,使用率是 12.5%,看起来风平浪静,但如果那个核上跑的是单线程的主流程,业务其实已经卡死了。
我在所有环境里都会把 CPU 时间拆开看,至少拆成四项:
- us(用户态):业务代码消耗,正常偏高说明计算密集,属于预期内。
- sy(内核态):系统调用、上下文切换、网络协议栈消耗,这个值长期超过 20% 通常意味着有大量小 IO 或者频繁的系统调用。
- wa(IO 等待):CPU 空闲但在等磁盘,这个值高说明瓶颈在存储层而不在 CPU 层。
- st(被抢占):在虚拟化环境里表示宿主机把你的 CPU 时间拿走了,这个值高说明问题不在你这台机器上,得往上找。
配合使用率还要看两个数:运行队列长度和上下文切换次数。运行队列长度(load average 的瞬时版本)如果长期大于 CPU 核数,说明有任务在排队,这时候即使使用率没到 100%,响应时间也已经劣化了。上下文切换次数则能帮你判断是不是有进程在空转。
关于 load average 还有一个老生常谈的误区:它是个绝对值,必须除以核数才有意义。load 8 在 4 核机器上是严重过载,在 32 核机器上属于轻松加愉快。我一般会把 load 除以核数做成一个“归一化负载”指标,告警就盯这个,比盯原始值靠谱得多。
2.2 内存:盯着 used 会把你带沟里
内存这块最常见的错误是直接采used或者free。Linux 的设计是“空闲内存不用白不用”,所以它会把大量内存拿去做页缓存(page cache),这时候free会显示得很低,但随时可以回收,完全不是问题。你要是拿free做告警,那机器从启动第二天开始就会一直响。
正确的做法是看MemAvailable(可用内存),这个值已经把可回收的缓存算进去了,是内核给出的“如果现在要申请内存,实际能拿到多少”的估计。如果老内核没有这个字段,可以用free + buffers + cached做一个近似,但精度差一些。
另外两个必须盯的数是swap 使用量和换页速率(si/so)。swap 使用量本身不一定要告警,很多环境会预留一部分 swap 作为缓冲;但换页速率一旦持续大于零,说明物理内存真的不够了,这时候系统响应会断崖式下跌。我见过最惨的一次是某台机器的 swap 换页速率常年在几十 MB/s,业务响应时间从 20ms 涨到 2 秒,而内存使用率图表上看起来只是“有点高”而已。
还有一个容易被忽略的:内存碎片化程度。在大页(hugepage)场景下,物理内存总量够但连续大块内存申请不到,会导致分配失败。这个指标不在常规采集范围里,需要单独看/proc/buddyinfo,一般用不到,但一旦遇到就是疑难杂症。
2.3 磁盘:容量、inode、延迟三个维度一个都不能少
磁盘是硬件资源监控里维度最多的部件,也是出事最频繁的。我通常会把它拆成四组指标。
第一组是容量:每个挂载点的总容量、已用、可用、使用率。这里有个细节,采集时要按挂载点采,而不是按设备采,因为同一个设备可能被挂到多个位置,报了设备级的数字对排查没帮助。
第二组是 inode:总量、已用、使用率。前面说的那个“容量 78% 但写不进去”的案例就是栽在这里。判断标准很简单,容量使用率和 inode 使用率任何一个超过阈值都要告警。
第三组是性能:每秒读写次数(IOPS)、吞吐量、平均等待时间(await)、队列深度、设备利用率(util)。这几个数里我最看重 await 和队列深度,util 反而参考价值有限——因为现代固态盘的 util 很容易跑到 100%,但延迟仍然很低,光看 util 会误判。
这里要解释一下为什么 await 比 util 重要。util 表示的是“设备有多少时间处于忙碌状态”,但这个忙碌可能是并行处理的;await 表示的是“一个 IO 请求从发出到完成花了多久”,这是业务真正感受到的延迟。一块盘 util 100% 但 await 只有 0.2ms,说明它忙得很健康;util 30% 但 await 有 80ms,说明它已经在挣扎了。
第四组是健康:磁盘的 SMART 属性,重点看重映射扇区数、待定扇区数、通电时间、温度。这些数据普通用户态读不全,通常需要特权进程或者直接读设备节点。重映射扇区数一旦开始增长,基本就是盘要坏的信号,我的做法是不设阈值,只要这个数在 24 小时内增加了就告警。
2.4 网络与硬件健康:容易被漏掉的那一半
网络指标的采集有个坑:要按网卡采,不要按总量采。一台机器上可能有业务网卡、存储网卡、管理网卡,混在一起算总量会掩盖单块网卡的问题。每块网卡至少要采:收发字节数、收发包数、错误包数、丢弃包数、带宽使用率。
其中错误包和丢弃包是最有价值的两个,因为它们是纯粹的增量指标,正常情况下应该恒等于零或者只在极缓慢地增长。我在告警规则里会写“5 分钟内错误包增量大于 0 就报”,这条规则的误报率极低,但抓到过好几次网线接触不良和光模块老化。
硬件健康这块就属于带外管理的范畴了。温度、风扇转速、电源状态、电压、内存纠错计数,这些信息由主板上的管理控制器收集,通过带外接口暴露。采集方式有两种:一种是定时去管理口拉取,另一种是让管理口主动上报。前者实现简单,后者实时性好。
这里必须提醒一句:带外采集的账号权限要给够但不要给全。很多管理口的默认账号权限过大,能执行关机、重启、改启动项,一旦泄露风险很高。我的做法是单独建一个只读账号,只允许读取传感器和日志,别的一概不给。
2.5 一张指标字典表,团队里谁看都清楚
指标定下来之后,强烈建议整理成一张字典表,把指标名、含义、采集间隔、保留周期、告警阈值、负责人全写进去。这张表的价值在于,半年后新同事接手,不用猜“这个cpu_usage_pct到底是包含 wa 还是不包含”。
下面是我常用的一张精简版,实际项目里会更长:
| 指标 | 含义 | 采集间隔 | 保留 | 告警条件 |
|---|---|---|---|---|
| cpu_usage_pct | 总使用率(含 wa、st) | 15s | 30 天 | 持续 10 分钟 > 85% |
| cpu_wait_pct | IO 等待占比 | 15s | 30 天 | 持续 5 分钟 > 20% |
| load_norm | load average ÷ 核数 | 30s | 30 天 | 持续 10 分钟 > 2 |
| mem_available_pct | 可用内存占比 | 15s | 30 天 | 持续 10 分钟 < 10% |
| swap_in_out_rate | 换页速率 | 15s | 30 天 | 持续 5 分钟 > 0 |
| disk_used_pct | 分区容量使用率 | 60s | 1 年 | > 85% 预警,> 92% 严重 |
| inode_used_pct | inode 使用率 | 60s | 1 年 | > 90% |
| disk_await_ms | IO 平均等待 | 15s | 30 天 | 持续 5 分钟 > 50ms |
| nic_err_delta | 网卡错误包增量 | 60s | 90 天 | 5 分钟内 > 0 |
| disk_realloc_sectors | 重映射扇区数 | 5min | 永久 | 24 小时内增长 |
| hw_temp_c | 关键部件温度 | 5min | 1 年 | > 80℃ |
这张表还有个副作用好处:写的过程中你会自然发现哪些指标是重复的、哪些是没人看的。我们第一版字典有 300 多项,整理完发现真正有人查的不到 80 项,剩下的全是可以降频或者直接砍掉的。
3. 采集层怎么落地:三种路径的取舍
3.1 代理式、无代理式、带外式,各管一段
采集路径基本就三种,各有各的适用面。
代理式是在每台机器上跑一个轻量采集进程,直接读本机的系统接口。优点是能拿到的指标最全、精度最高、支持自定义脚本;缺点是要往每台机器上部署,版本管理麻烦,而且采集进程本身要占资源、要考虑它挂了怎么办。适合操作系统内部指标,这是主力方案。
无代理式是不在目标机上装东西,通过远程协议去拉数据。优点是部署成本为零,适合网络设备、存储设备、打印机这类装不了代理的东西;缺点是可采集的指标少,且采集频率受限于远程调用的开销,一般拉不到 15 秒这个级别。
带外式是走管理控制器的通道,前面说过了,专管硬件健康。它的优点是即使操作系统宕机了照样能采到数据,这在排查“机器莫名重启”这类问题时是决定性优势;缺点是采集慢、数据粒度粗。
我在实际项目里三样都用,分工很明确:操作系统指标走代理,网络和存储设备走无代理,硬件健康走带外。不用纠结哪个更好,它们解决的问题本来就不重叠。
3.2 采集频率、超时、并发,三个数要一起定
采集频率的定法在 1.2 节已经说了,按层来。这里补两个经常被忽略的参数。
超时时间必须小于采集间隔,否则上一轮还没结束下一轮就开始了,会堆积。一般设成采集间隔的三分之一到二分之一,15 秒间隔配 5 秒超时是个常见配置。超时之后不是简单丢弃,而要打一个“采集失败”的标记指标,这个标记本身也是要监控的——我曾经有台机器的采集代理因为磁盘满了导致采集全挂,但因为它挂得“很干净”,看板上直接是空白,没人发现,直到业务出问题才发现数据已经缺了三天。
并发数要根据目标机器规模调。每轮采集如果对 500 台机器同时发起,采集端自己的网络和文件描述符会先顶不住。我的经验值是单实例并发控制在 100 到 200 之间,超了就分片,多起几个采集实例,每个实例负责一部分机器。
提示:采集端自身也要被监控。CPU、内存、打开的文件描述符数、队列积压长度,这几个指标一旦异常,说明采集链路已经不可靠了,此时看到的所有业务指标都不可信。
3.3 标签设计:基数炸了比没数据还难受
时间序列数据库里,每个指标配上一组标签就形成一条独立序列。标签设计不当会直接把存储打爆,这个坑非常常见。
典型的错误是给指标加上高基数的标签,比如把进程 ID、请求 ID、文件路径、用户 ID 做成标签。一台机器上跑几百个进程,进程 ID 还随时在变,标签组合数瞬间上万,存储直接崩。
正确做法是:标签只放低基数的维度,比如机房、机柜、机器角色、操作系统类型,这些加起来最多几十种组合。高基数的信息不要做成标签,要么做成指标值本身(比如“某个进程组的内存占用”作为数值),要么放在日志里查。
还有一个具体建议:给每台机器加一个稳定的、人工可读的标识,比如“角色-机房-序号”这种命名,不要用随机生成的机器码。因为排查问题时你是靠这个标识去定位机器的,用机器码等于每次都要多查一次映射表。
3.4 一个最小可用的采集配置长什么样
下面这段是我常用的采集配置骨架,思路是分组定义、每组独立频率。字段名做了通用化处理,核心结构在任何采集器上都能对应上。
global: scrape_interval: 30s scrape_timeout: 10s external_labels: site: "机房A" env: "prod" scrape_configs: - job_name: "os_fast" scrape_interval: 15s static_configs: - targets: ["10.0.1.11:9100", "10.0.1.12:9100"] labels: role: "compute" relabel_configs: - source_labels: ["__address__"] regex: "([^:]+):.*" target_label: "host" replacement: "$1" - job_name: "os_slow" scrape_interval: 60s static_configs: - targets: ["10.0.1.11:9101", "10.0.1.12:9101"] - job_name: "bmc" scrape_interval: 300s scrape_timeout: 30s static_configs: - targets: ["10.0.9.11", "10.0.9.12"]几个细节值得说。第一,os_fast和os_slow是两个独立任务,指向同一批机器的不同端口,这样频率差异通过端口隔离,互不影响。第二,relabel_configs里把地址里的 IP 抽出来做成host标签,是为了让后续查询能用可读的名字而不是带端口的地址。第三,bmc这个任务的超时给到了 30 秒,因为管理口响应普遍比较慢,超时给短了会大量失败。
4. 从零搭一套最小可用监控
4.1 环境与目录规划
先定目录结构,这个看起来是小事,但规划不好后面迁移数据会非常痛苦。我习惯这样分:
/opt/monitor/ ├── collector/ # 采集端程序与配置 │ ├── conf/ │ └── data/ ├── storage/ # 时序数据落盘目录 │ ├── wal/ │ └── chunks/ ├── dashboard/ # 看板配置 └── rules/ # 告警规则存储目录一定要单独挂一块盘,而且要按顺序写入做优化。原因很直接:时序数据是持续追加写,如果和操作系统盘混在一起,采集端写 WAL 的时候会和系统的其他 IO 抢资源,反过来影响被监控机器本身的性能——这就本末倒置了。
容量规划按 1.3 节的算法来。假设算出来一个月要 45 GB,我会直接给 200 GB,留出四倍余量。多留的理由不是浪费,而是历史数据在排查问题时经常需要回溯,删除是不可逆的。
4.2 采集端落地与自监控
采集端部署完之后,第一件事不是去看业务指标,而是确认采集端自己能正常工作。要检查的点有这么几个:
- 采集目标是不是全部处于“可达”状态,有没有一直失败的;
- 每轮采集的耗时分布,最慢的那台花了多久;
- 采集端进程自身的 CPU 和内存占用,正常应该在个位数百分比和几百 MB 以内;
- 数据写入是否持续,有没有断点。
这几项确认完,再去看看板上有没有数据。这个顺序很重要,因为如果采集端本身有问题,你看到的所有“业务指标异常”都可能是假的。
4.3 存储与降采样:长期趋势靠它
原始数据按 15 秒采、保留 30 天,长期趋势靠降采样。降采样就是把原始点按时间窗口聚合成更粗的粒度,比如把 15 秒的点每 4 个聚成一个 1 分钟的点,保留聚合后的最小值、最大值、平均值。
为什么要保留最大值?因为容量规划和性能回溯时,平均值会掩盖尖峰。一块盘平均 await 只有 3ms,但每天有几个时段冲到 200ms,如果只留平均值,你永远发现不了这个问题。
我的降采样策略一般是三层:
| 层级 | 粒度 | 保留 | 用途 |
|---|---|---|---|
| 原始 | 15s | 30 天 | 精准排查 |
| 一级降采样 | 1min | 180 天 | 季度趋势 |
| 二级降采样 | 10min | 2 年 | 容量规划 |
三层加起来,存储成本大约是只留原始的 1.3 倍左右,但能把历史视野从一个月拉到两年,性价比很高。
4.4 看板怎么排才有人看
看板设计上我踩过最大的坑是“什么都往上放”。第一版看板有十几个图,密密麻麻,结果没人看。后来改成三层结构,使用率一下就上来了。
第一屏是总览,只放全局状态:多少台机器在线、多少条告警在响、几台机器的磁盘快到线了。这一屏的目标是让人三秒钟判断“今天要不要干活”。
第二屏是单机详情,点进某台机器才看到它的完整曲线。CPU 四项、内存三项、每块盘、每张网卡,按部件分组。
第三屏是趋势,容量增长率、周同比、月度峰值,给规划用。
每张图我都会标上阈值线,红黄两条。没有阈值线的图,看的人得自己心里有把尺子,那就等于没有标准。
4.5 验证:让监控自己先被打一遍
系统搭好之后,一定要做一次主动验证——人为制造负载,看监控能不能抓到。我通常会做这么几项:
用压力工具把 CPU 压到 90% 以上持续几分钟,看看板上是否出现对应的曲线,告警是否在预期时间内触发;用大文件写入把磁盘占满,验证容量告警和 inode 告警是否分别生效;用工具模拟网络丢包,验证错误包告警是否触发。
这一步做完最大的价值是把告警延迟摸清楚。有些告警配了“持续 5 分钟”的条件,从故障发生到告警发出实际要 5 到 6 分钟,如果你不知道这个数字,出事时就会误以为告警系统坏了。
5. 告警阈值怎么定才不吵人
5.1 静态阈值不是不行,但要分场景
静态阈值的毛病是“一刀切”:所有机器都用 85%,但一台跑离线批处理的机器和一个跑在线服务的机器,85% 的含义完全不同。前者可能就是正常的工作状态,后者已经是危险信号。
我的做法是按角色分组定阈值。在线服务类机器阈值收紧(CPU 75%、内存可用 20%),离线计算类放宽(CPU 90%、内存可用 10%)。分组方式就是前面说的用标签区分,规则里按标签筛选,不用为每台机器单独写规则。
对于波动特别大的指标,静态阈值确实不好使,这时候可以用动态基线:取过去 7 天同一时段的均值,超过均值 3 倍标准差就告警。但动态基线有个前提,就是业务得有稳定的周期性,如果没有,基线反而会产生大量误报。我一般只用动态基线处理带宽这类周期性明显的指标,其他还是用静态阈值加分角色。
5.2 用持续时长压掉抖动
即使阈值定得合适,瞬时抖动也会带来大量噪音——一次编译、一次备份、一次日志切割,都能让 CPU 瞬间飙到 100%。
解决办法就是给告警加“持续时间”条件,比如“CPU 使用率大于 85% 且持续 10 分钟”。这个时长怎么定?有个经验做法:先定一个容忍窗口,也就是“这个异常持续多久我才真的要处理”,然后取这个时间的一半作为告警条件,再乘 1.5 倍作为恢复条件。比如容忍 10 分钟,那告警持续 5 分钟触发,恢复条件是降到阈值以下持续 7.5 分钟。恢复条件比触发条件严格,可以避免告警在阈值附近来回跳。
5.3 告警分级与收敛
告警不分级的结果是所有告警看起来一样急,最后的结果就是没人当回事。我一般分三级:
P1 立即处理:磁盘马上写满(92% 以上)、硬件报错(重映射扇区增长、内存纠错计数增长)、机器失联。这类告警走电话或者即时通知,要求有人立刻看。
P2 当天处理:CPU 持续高、内存可用跌破 10%、磁盘 IO 延迟持续超标。走工作群通知,当天有人跟进就行。
P3 计划处理:容量超过 80%、inode 超过 85%、温度偏高。走工单,排进本周计划。
分级之后再配合收敛:同一台机器同一类告警,5 分钟内只发一次;同一个机柜 3 台以上机器报同类告警,合并成一条“机柜级”告警发出来,这时候大概率是机柜的交换机或者供电有问题,而不是三台机器同时坏了。
6. 常见问题与排查实录
6.1 现象、原因、处理速查表
下面这张表是我这几年攒下来的,基本覆盖了硬件资源监控里八成的“为什么数据不对”的问题:
| 现象 | 常见原因 | 处理方式 |
|---|---|---|
| 看板某台机器突然没数据 | 采集代理挂了 / 网络不通 / 目标端口改了 | 先确认代理进程存活,再手动请求一次采集端点 |
| 数据有大段空洞但代理正常 | 采集超时堆积 / 存储写入被阻塞 | 查采集端队列长度和写入延迟,调大超时或降低并发 |
| CPU 使用率加起来不等于 100% | 采集时间点不一致,各项是分别读的 | 改成一次读取全部字段再计算,或接受微小误差 |
| 内存使用率一直很高但系统正常 | 采的是 used,没算 page cache | 改采 MemAvailable |
| 磁盘使用率不高但写不进 | inode 耗尽 | 单独采集并告警 inode |
| 告警频繁误报 | 阈值太紧 / 没加持续时长 | 按角色重定阈值,加持续时间条件 |
| 同一条告警反复发 | 没有收敛和恢复条件 | 加静默窗口,恢复条件设置得比触发更严格 |
| 硬件温度曲线看不到 | 没走带外采集 | 补一条带外采集通道,用只读账号 |
| 历史数据查不到 | 降采样时只留了平均值 | 降采样至少保留最小值、最大值、平均值三个 |
6.2 几个只有踩过才知道的细节
第一个是采集时间戳对齐。不同采集器对时间戳的处理不一样,有的用采集时刻,有的用数据生成时刻,混用会导致同一条曲线在图上出现锯齿。统一规定用采集时刻打时间戳,并且在采集端就做,别留给存储层去补。这件事看起来小,但跨采集器做关联查询时会非常痛苦。
第二个是时钟同步。所有被监控机器的时钟必须同步,否则你在看板上把两台机器的曲线叠在一起看,会得出完全错误的结论。有一次排查一个“两台机器性能相关性”的问题,看了半天发现是因为其中一台机器时钟慢了 40 秒,曲线叠在一起是错的。现在我在采集时会附带一个本机时间与标准时间的偏差指标,超过 1 秒就告警。
第三个是别把监控数据放在被监控的机器上。这个错误很基础,但确实见过。存储和看板必须独立部署,至少要放在一台不承担业务负载的机器上。理由是万一被监控机器宕机,你至少还能看到它宕机前的数据,能判断是突然失联还是逐步恶化。
第四个是保留一份“已知正常”的快照。每次系统变更或者业务上线前,导出一份当前的核心指标快照存起来。事后判断“这个数是不是变高了”,有个基准比什么都有用。这个习惯帮我省过好几次扯皮——业务方说系统变慢了,把两个月前的快照拉出来一比,其实那个接口的延迟一直是这个数。
6.3 一点个人体会
硬件资源监控做到最后,比拼的不是采集了多少指标,而是“哪些指标能被信任”。我现在的原则很朴素:每个上线的告警规则,我都要求它能回答两个问题——这条告警响的时候,我第一步该做什么;如果这条告警一年都没响过,它是不是可以删掉。回答不了第一个问题的规则不上线,回答不了第二个问题的规则三个月后强制复核一次。靠着这两条,我们把告警数量从最初的四百多条压到了六十条出头,反而抓到了更多真正的问题。
另外还有一个具体的做法值得推荐:给每台机器建一个“硬件履历”,把磁盘的 SMART 变化、内存纠错计数的增长、风扇转速的缓慢下降都记录下来,按时间线排。硬件的失效几乎都是有前兆的,只是这个前兆跨度可能是几个月。把履历拉出来看,很多“突然坏掉”的部件其实早就在打信号了。