![高 IO 负载导致 rrdgraph 生成失败](https://linux22.com/image/639415/%E9%AB%98%20IO%20%E8%B4%9F%E8%BD%BD%E5%AF%BC%E8%87%B4%20rrdgraph%20%E7%94%9F%E6%88%90%E5%A4%B1%E8%B4%A5.png)
我们有一个 4 核 CPU 生产系统,它可以执行大量的 cronjobs,具有恒定的 proc 队列和通常约为 1.5 的负载。
在夜间,我们用 postgres 进行一些 IO 密集型操作。我们生成一个显示负载/内存使用情况的图表 (rrd-updates.sh)。在高 IO 负载情况下,此操作有时会“失败”。这种情况几乎每晚都会发生,但并非在每次高 IO 情况下都会发生。
我的“正常”解决方案是对 postgres 内容进行 nice 和 ionice,并提高图形生成的优先级。但是这仍然失败了。使用 flock,图形生成是半线程防护的。我确实记录了执行时间,对于图形生成,在高 IO 负载期间,它最多需要 5 分钟,似乎导致图形丢失长达 4 分钟。
时间范围与 postgres 活动完全匹配(这有时也会在白天发生,但并不常见)将 Ionicing 提高到实时优先级(C1 N6 graph_cron vs C2 N3 postgres),将 nicing 提高到 postgres 之上(-5 graph_cron vs 10 postgres)并没有解决问题。
假设数据没有被收集,那么另一个问题是 ionice/nice 不知何故仍然无法工作。
即使 IOwait 为 90% 且负载为 100,我仍然能够免费使用数据生成命令,延迟可能不超过 5 秒(至少在测试中)。
遗憾的是,我无法在测试中准确重现这一点(只有一个虚拟化的开发系统)
版本:
内核2.6.32-5-686-bigmem
Debian Squeeze rrdtool1.4.3
硬件:SAS 15K RPM HDD,带有硬件 RAID1 中的 LVM
安装选项:扩展使用 rw,errors=remount-ro
调度程序:CFQ
crontab:
* * * * * root flock -n /var/lock/rrd-updates.sh nice -n-1 ionice -c1 -n7 /opt/bin/rrd-updates.sh
Oetiker 先生在 github 上发布的关于 rrdcache 的 BUG 似乎与此有关:
https://github.com/oetiker/rrdtool-1.x/issues/326
这实际上可能是我的问题(并发写入),但它不能解释 cronjob 没有失败。假设我实际上有 2 个并发写入flock -n
将返回退出代码 1(根据手册页,在测试中得到确认)因为我也没有收到带有输出的电子邮件,而且观察到 cronjob 实际上在其他时间都运行良好,我不知何故感到迷茫。
示例输出:
根据评论我添加了更新脚本的重要来源。
rrdtool update /var/rrd/cpu.rrd $(vmstat 5 2 | tail -n 1 | awk '{print "N:"$14":"$13}')
rrdtool update /var/rrd/mem.rrd $(free | grep Mem: | awk '{print "N:"$2":"$3":"$4}')
rrdtool update /var/rrd/mem_bfcach.rrd $(free | grep buffers/cache: | awk '{print "N:"$3+$4":"$3":"$4}')
我错过了什么或者我可以在哪里进一步查看?
请记住:生产系统没有开发、没有堆栈跟踪或类似可用或可安装的内容。
答案1
我猜不是 rrdtool 无法更新图表,而是此时无法测量数据。顺便说一句,您测量 CPU 和内存统计数据的方法是错误的,因为它会立即给出结果。CPU 和内存负载可能会在 60 秒间隔内发生巨大变化,但您只会取一个值。您真的应该考虑获取 SNMP 数据,它可以给出一个间隔的平均数据。此外,整个管道似乎比 snmpget 调用更昂贵、更慢。这可能是差距的主要原因。