本文转自: 作者:ailms
RRDtool 简介
[color=blue]
**********************************************************************************************************************
注 :该教程参考了如下内容 :
A)官方文档 :
B)abel 兄的大作 :
作者 :ailms <>
版本 :v1
最后修改 :2006/11/18 0:06
**********************************************************************************************************************
[/color]
在介绍 RRDtool 之前,让我们先回顾一下它的前身:MRTG。相信只要做网管工作的朋友,对 MRTG 这个软件一定不会陌生,
至少也可能听过。MRTG 可以通过 SNMP 协议直接访问 SNMP Object ,例如 ifInOctect 和 ifOutOctect ;也可以通过外部
script 的方式,来监测cpu、内存、磁盘利用率、数据库的表空间利用率等信息。只要把 MRTG 放入 crontab 中让其自动运行,
MRTG 就可以自动为你绘制出每天、每周、每月、每年的统计图表。 MRTG 甚至还为你提供了自动生成配置文件的 cfgmaker 和
自动生成 HTML 页面的 indexmaker 这两个工具,让你省去逐个编写 cfg 文件的痛苦。到目前为止,还有很多人在使用它。它现在
有 Unix、Windows 各种平台,windows 平台上甚至出现了 PRTG 这样和 MRTG 很象的东东,轻点鼠标就可以漂亮的完成工作。
既然如此,我们为什么还要介绍 RRDtool 呢?先让我们看几个问题,几个在 MRTG 使用中常见的问题 :
[size=4] 一)MRTG 不能作什么?[/size]
A)[color=blue]MRTG 一张图表只能显示2个对象,一个输入,一个输出。[/color]如果你想同时显示多个对象呢?例如笔者的单位有12台服务器。如果想
把它们的负载情况都显示在一个图表上,MRTG 至少需要6张图。
B)[color=blue]MRTG无法回放数据。[/color]MRTG 的图是自动生成的,所采用的数据也是由 MRTG 自己提取的,例如5分钟平均的记录有288条, MRTG每20分钟合并一次,
每次合并4个记录。在50个小时后,288条记录将全部变成20分钟平均的数据。如果你想回放这些数据怎么办呢?对不起,只能去
看第2个图了(每周)。
C)[color=blue]MRTG 只有 COUNTER 和 GAUGE 这两种计算类新。[/color]如果我要监测两个数值型的对象之间的大小,它们之间的差值可以是正数,也可以
是负数。MRTG 能实现吗?笔者在多次试验中发现,MRTG 对于负数的和 ‘.15’ 这样格式的小数(通常都是bc的输出)的识别会出错。
例如把 ‘.72’ 识别为 72,把 -1 识别为 1。
D)[color=blue]MRTG 无法实现有条件的绘图。[/color]有时候我们只想看某个服务器在一年之中的宕机时间,正常时间我们不关心;或者我们想看当前值和去年同期相比究竟如何? 这些都是
MRTG无法做到的
[size=4]二) MRTG 的优点[/size]
那 MRTG 和 RRDtool 相比就没有优点了吗?也不是。简单、方便就是它的最大优点。
(MRTG 中还有一个好东西就是自动告警功能,相比之下,RRDtool 在这方面的配置比较复杂,
还不如直接作到 shell script中)
前面提到 MRTG 能够通过 cfgmaker 和 indexmaker 快速建立配置文件和HTML页面。而 RRDtool 在这两方面都需要自己动手。
数据的采集→插入数据→提取数据→绘图→建立 HTML ,这些步骤都是需要你自己动手的。RRDtool 给了使用它的人最大程度的自由。但这种
自由对于新手或者没有耐心的人来说可能是一种考验。相比之下,MRTG 就容易上手多了。
[size=4] 三) RRDtool 的定义[/size]
RRDtool 代表 “Round Robin Database tool” ,作者同时也是 MRTG 软件的发明人。官方站点位于 。
所谓的“Round Robin” 其实是一种存储数据的方式,使用固定大小的空间来存储数据,并有一个指针指向最新的数据的位置。我们可以把用于存储
数据的数据库的空间看成一个圆,上面有很多刻度。这些刻度所在的位置就代表用于存储数据的地方。所谓指针,可以认为是从圆心指向这些刻度的
一条直线。指针会随着数据的读写操作自动移动。要注意的是,这个圆没有起点和终点,所以指针可以一直移动,而不用担心到达终点后就无法前进
的问题。在一段时间后,当所有的空间都存满了数据,就又从头开始存放。这样整个存储空间的大小就是一个固定的数值。所以RRDtool 就是使用类似
的方式来存放数据的工具,RRDtool 所使用的数据库文件的后缀名是 ‘.rrd’。
[size=4] 四)RRDtool 的特殊之处[/size]
A) 首先 RRDtool 存储数据,扮演了一个后台工具的角色。但同时 RRDtool 又允许创建图表,这使得 RRDtoo 看起来又像是前端工具。其他的数据库
只能存储数据,不能创建图表。
B) RDtool 的每个 rrd 文件的大小是固定的,而普通的数据库文件的大小是随着时间而增加的
C) 其他数据库只是被动的接受数据, RRDtool 可以对收到的数据进行计算,例如前后两个数据的变化程度(rate of change),并存储该结果。
D) RRDtool 要求定时获取数据,其他数据库则没有该要求。如果在一个时间间隔内(heartbeat)没有收到值,则会用 UNKN 代替,其他数据库则不会这样做
[size=4] 五)总结RRDtool 和 MRTG 的不同之处[/size]
A) MRTG 是采用配置文件的方式来监控的;
RRDtool 则没有配置文件一说。所有操作都是通过命令(也可以写成script方式)执行
B) MRTG 有自动采集数据的功能(通过 snmp);
RRDtool 没有,需要手工或者通过 shell/perl 脚本来获取数据
C) MRTG 每次运行都会更新图片和日志;
RRDtool 默认知识接收数据,并不会绘图,除非手工执行 graph 命令
D) MRTG 采用明文的 log 方式存放历史数据;
RRDtool 采用数据库的方式来存放数据;
E) MRTG 无法回放日志数据,因为 MRTG 会对日志进行合并;
RRDtool 采用 RRA 的概念,把不同统计周期的数据单独存放,所以可以做到历史数据的回放功能
F) MRTG 的 log 中每种周期的记录的数量是自动维护的;
RRDtool 的 RRA 中的记录数是可以自定义的。
G) MRTG 中数据的统计时间间隔是固定的,例如 5分钟平均,30分钟平均,2小时平均,1天平均;
RRDtool 可以任意设置(试过1分钟一次)
H) MRTG 一张图只能显示2个对象;
RRDtool 可以显示多个。
I) MRTG 的数据类型只有 COUNTER 和 GAUGE 两种;
RRDtool 有5种,COUNTER、GAUGE、DERIVE、ABSOLUTE、COMPUTE
J) MRTG 的图表只能显示当前值、最大值、平均值;
RRDtool 可以显示当前值(LAST)、初值(FIRST)、最大值(MAX)、最小值(MIN)、平均值(AVG)、总和(TOTAL)等
K) MRTG 绘图方式只有 AREA、LINE 方式;
RRDtool 则有 AREA、LINE(1|2|3)、STACK 方式;
L) MRTG 负责搜集、存储、绘图、建档(HTML);
RRDtool 只负责存储、绘图这两个阶段,所以需要自己建立 HTML 文件
M) MRTG 的运算功能较差;
RRDtool 可以通过 CDEF 对取出来的数据进行算术和逻辑运算;
N)MRTG 只能原原本本的显示数据;
RRDtool 可以对数据进行处理,或者有条件的显示;
看来 RRDtool 的功能是不是比 MRTG 强很多呢?!
[color=red]具体的差异目前就只能想到这些,不知各位还有没有什么补充呢? !!^_^ !![/color]
相信这么讲的话还是比较抽象的,不过不用急,目前只是一个开始而已。
下一节我们开始讲如何安装 RRDtool 。
[ 本帖最后由 ailms 于 2006-12-4 09:24 编辑 ]
--------------------------------------------------------------------------------
zhdh1999 回复于:2006-12-03 23:09:06
收藏 中。。。:D
谢谢lz
--------------------------------------------------------------------------------
platinum 回复于:2006-12-04 07:45:38
希望你能将这些贴子合并,现在这样太分散了不便于管理和阅读
--------------------------------------------------------------------------------
ailms 回复于:2006-12-04 09:21:41
回斑竹大人,之前是考虑到内容太长,放在一个贴子里可能看得太类累了。
我现在已经把全部内容放到一个帖子了,不过有些原来的贴子由于被回复了,所以删除不了。
RRDtool 的安装
[color=blue]
**********************************************************************************************************************
注 :该教程参考了如下内容 :
A)官方文档 :
B)abel 兄的大作 :
作者 :ailms <>
版本 :v1
最后修改 :2006/11/18 0:06
**********************************************************************************************************************
[/color]
[size=4] 一) 安装前的准备[/size]
以 Redhat 9 为例 :
如果要安装 source 包,请到 :,
如果要安装 RPM 包,请到 。
不管采用那种方式,都需要先确认当前系统中是否有安装如下RPM包 :
[root@dns1 bob]# rpm -qa |grep zlib
zlib-1.1.4-8
zlib-devel-1.1.4-8
[root@dns1 bob]#
[root@dns1 bob]# rpm -qa |grep libpng
libpng-1.2.2-20
libpng10-devel-1.0.13-11
libpng10-1.0.13-11
libpng-devel-1.2.2-20
[root@dns1 bob]#
[root@dns1 bob]# rpm -qa |grep freetype
freetype-utils-2.1.3-6
freetype-devel-2.1.3-6
freetype-2.1.3-6
freetype-demos-2.1.3-6
[root@dns1 bob]#
[root@dns1 bob]# rpm -qa |grep libart_lgpl
libart_lgpl-2.3.11-2
libart_lgpl-devel-2.3.11-2
bob]#
[size=4] 二)RPM 方式安装[/size]
Redhat 9 上 RRDtool 相关的 rpm 包如下,并非所有都要装,有些只是同一个rpm包不同版本而已。
perl-rrdtool-1.0.50-3.rh9.rf.i386.rpm
perl-rrdtool-1.2.13-1.rh9.rf.i386.rpm
perl-rrdtool-1.2.15-1.rh9.rf.i386.rpm
php-rrdtool-1.0.50-3.rh9.rf.i386.rpm
rrdtool-1.0.50-3.rh9.rf.i386.rpm
rrdtool-1.2.13-1.rh9.rf.i386.rpm
rrdtool-1.2.15-1.rh9.rf.i386.rpm
rrdtool-devel-1.0.50-3.rh9.rf.i386.rpm
rrdtool-devel-1.2.13-1.rh9.rf.i386.rpm
rrdtool-devel-1.2.15-1.rh9.rf.i386.rpm
tcl-rrdtool-1.2.13-1.rh9.rf.i386.rpm
[size=4] 三)source 方式安装[/size]
Source 包就简单了,就一个 :
下面就以 Source 包的方式安装 :
在开始 build RRDtool 之前,要先决定两件事 :
第一是在那个目录下执行 build 操作。
第二是想把 RRDtool 安装在什么位置。
例如 :
[root@dns1 bob]# BUILD_DIR=/tmp/rrdbuild
[root@dns1 bob]# INSTALL_DIR=/usr/local/rrdtool-1.2.14
[root@dns1 bob]# mkdir -p $BUILD_DIR
[root@dns1 bob]# cd $BUILD_DIR
[root@dns1 rrdbuild] # tar zxf rrdtool-1.2.14.tar.gz
[root@dns1 rrdbuild] cd rrdtool-1.2.14
[root@dns1 rrdbuild] ./configure --prefix=$INSTALL_DIR && make && make install
然后需要的就是耐心的等待,正常情况下应该是没有问题的,如果还是报错,注意检查是否满足上面的 RPM 需求。
当重新出现 shell 提示符时,表示安装结束。这时候可以执行 rrdtool 命令看是否安装成功
[size=4] 四)测试安装是否成功[/size]
引用:
[root@dns1 rrdtool-1.2.14]# /usr/local/rrdtool-1.2.14/bin/rrdtool
RRDtool 1.2.14 Copyright 1997-2006 by Tobias Oetiker <>
Compiled Oct 14 2006 10:55:28
Usage: rrdtool [options] command command_options
Valid commands: create, update, updatev, graph, dump, restore,
last, first, info, fetch, tune, resize, xport
RRDtool is distributed under the Terms of the GNU General
Public License Version 2. ()
For more information read the RRD manpages
[root@dns1 rrdtool-1.2.14]#
如果出现上述输出则表示安装已经成功。不过每次都要输入这么长的命令岂不是很麻烦。最好加入到 PATH 中去。
[root@dns1 rrdtool-1.2.14]# vi ~/.bashrc
把 PATH 一行修改为 :
PATH=$PATH:$HOME/bin:/usr/local/rrdtool-1.2.14/bin
整个安装过程到此就结束了,是不是很简单呢 ^_^
如果你是想安装到别的地方,只要把上面对应的 /usr/local/rrdtool-1.2.14 替换为你想要的目录就可以了
好了,下一节我们讲MRTG和 RRDtool 实施前的规划问题。
[ 本帖最后由 ailms 于 2006-12-4 09:36 编辑 ]
--------------------------------------------------------------------------------
ailms 回复于:2006-12-04 09:22:13
前期规划
[color=blue]
**********************************************************************************************************************
注 :该教程参考了如下内容 :
A)官方文档 :
B)abel 兄的大作 :
作者 :ailms <>
版本 :v1
最后修改 :2006/11/18 0:06
**********************************************************************************************************************
[/color]
可能大家会觉得奇怪,做个 RRDtool 还要规划什么?俗话说:磨刀不误砍柴工。好的规划必须具备灵活性、可扩展性,否则会给
将来的使用带来不少的麻烦。我们先谈一下 MRTG 的规划,再谈 RRDtool 的规划。
[size=4]一)MRTG 的前期规划[/size]
A)[color=blue]想要监测监测什么对象?[/color]并列出一个清单;
B)[color=blue]想要以什么方法来取得数据?[/color]是通过 SNMP 还是 shell 、perl 。如果使用 SNMP ,监测对象所在主机
的 SNMP 服务安装了吗?是否配置完毕;
C)[color=blue]每个对象的监测时间是多长时间一次?[/color]并以此对监测对象进行分类。例如笔者本人共用 MRTG 监测了 80 多个对象,并根据
内容分成四类 :
重要状态方面 : 例如 HACMP 的切换动作监控;Oracle 服务的状态;LVM 中的 vg 是否在线;服务器是否宕机等。这些监
测对象对于一个系统的运行来说都是十分重要的,一旦发生故障,需要立即处理的。所以对于这类对象,按最
小时间间隔(5分钟一次)设置
I/O性能方面 :主要是 I/O 吞吐量、I/O 服务时间方面的监测。这类对象是7分钟一次
次要状态方面 :例如 cpu利用率、内存利用率、在线人数、温度、拨号用户人数等。20分钟一次
利用率方面 : 由于实际应用的问题,所以对利用率比较关心。单独拎出来做一块监测。主要是监控Oracle 的各个表空间的利
用率,以及LVM磁盘系统各个分区的利用率。每25分钟一次
监控机本身 :负责监控的监控机本身也需要监控。主要监控当前监测的对象数量,以及系统负荷。这类就30分钟一次。
D)[color=blue]每个对象一个 cfg 文件?还是全部集中在一个 cfg 文件中呢?[/color]我本人还是比较倾向于每个 Target一个 cfg 文件,每个 cfg 中都定
义 Workdir、Language 这两个选项。针对上面的5个分类,建立5个 “大的”cfg 文件,再利用 MRTG 中的 Include 功能导入一个个
“小的”、具体的 cfg 文件。这样当日后对某个监测对象进行修改时(例如修改数据的获取脚本,或者修改图片的外观),可以单独测试
该对象。不用连同其他对象也一起跑一次,节省不少时间。如果想取消那个对象的监测,在前面提到的那个“大的”cfg 文件中,把对应
的 Include 语句注释掉就可以了,是不是更方便呢?
E)[color=blue]为个监控对象起一个合适的名称[/color]。一般用 的方式。这一步也满重要的。一开始不注意,随便给个名字,等到后来自己都
搞不清楚了,建议一开始就规划好。如果要使用 MRTG 的告警功能,就更应该好好规划了,要不然收到告警邮件都不知道是那个对象,那个机
器出现问题,白白浪费时间。
F)[color=blue]是否需要用到 MRTG 的告警功能。[/color]MRTG 有告警功能,可以设置输入/出的最大值,最小值。超过限制就会调用 ThreshProgI 和 ThreshProgO
选项指定的程序。我一般用发送邮件和HTML配合的方式。下面是告警部分的截图 :
差不多也就这些了,就可以开始动手写 script 了。
[size=4] 二)RRDtool 的前期规划[/size]
RRDtool 的前期规划相对多一点,因为 RRDtool 很多东西需要自己设定。除了上述 MRTG 考虑的几点之外,我一般还考虑以下几点 :
A)[color=blue]是一个 RRD 文件中包括多个监测对象(DS),还是分成多个 RRD 文件 ?[/color]RRDtool 提供了 tune 操作,可以增加监测对象或者删除 RRD 文
件中的某个对象,而且绘图时也可以指定要画的是那个对象,这点看个人喜欢而定。
B)[color=blue]如何统计取得的数据 :[/color]MRTG 是固定的,5分钟、20分钟、2小时、1天。RRDtool 则可以自己设置
C)[color=blue]如何保存/统计这些数据 :[/color]这是和 MRTG 不同的地方。MRTG log 的建立和维护是自动的,RRDtool 的数据存放
则需要自己定义。但我们可以参照 MRTG 的方式:
每日统计图(5分钟平均) : 600 个,大约2天的时间
每周统计图(20分钟平均) : 600 个,大约8天的时间
每月统计图 (2小时平均) : 600 个,50 天的时间
每年统计图 (1天平均) :730 个, 2年的时间
D [color=blue]要以什么方式绘图 :[/color]MRTG 只有曲线(LINE)和方块(AREA)两种;RRDtool 除了这两种外,还有一种是 STACK 方式。就是在前一个曲线或者方
块的基础上绘图图,而不是直接从 X 轴开始绘图。这样绘制出来的图比较清晰,不会出现交叉的现象,但此时 Y 轴的值等于当前对象的值加上前一
个绘图对象的值。例如前一个对象(cpu 的系统进程利用率)的值是10,采用的是 AREA 方式绘图。当前对象(cpu 的用户级进程的利用率)是5,
采用的是 STACK 方式,则“cpu的用户级进程利用率”对应的Y轴刻度是10+5=15;所以如果不加说明,别人可能会误解。
[size=4]三)实际例子[/size]
A)[color=blue]搞清楚究竟想要监测什么对象 :[/color]监测本地主机的网络流量。包括 eth0 和 lo 接口的流量。
B)[color=blue]想要以什么方法来取得数据 :[/color]sar 也可以统计网卡接口的流量。但这里我们用 SNMP ,访问 ifInOctets 和 ifOutOctets 。
假设脚本名称是 get_eth0_traffic.sh 和 get_lo_traffic.sh
C)[color=blue]每个对象的监测时间是多长时间一次 :[/color]5分钟
D)[color=blue]是采用一个 RRD 文件还是多个 :[/color]2个 RRD 文件,一个是 eth0.rrd,一个是 lo.rrd
E)[color=bl;ue]为每个监测对象起名 :[/color]分别是 eth0_in ,eth0_out ,lo_in ,lo_out
F)[color=blue]统计频率 :[/color]5分钟、20分钟、2小时、1天
G)[color=blue]如何保存统计数据 :[/color]600个、600个、600个、730个
H)[color=blue]要以什么方式绘图 :[/color]目前暂不考虑该问题。等到实际绘图时再体验。
[color=red]注 :实际上我们可以把数据的插入、绘图一起做到 get_eth0_traffic.sh 和 get_lo_traffic.sh 中,但目前这两个脚本只是负责取数据并输出而已,
到最后我们再把这些功能合并到一起。[/color]
[size=4] 四)下面是脚本的内容[/size]
[root@dns1 bob]# cat get_eth0_traffic.sh
#!/bin/bash
# 首先取得 eth0 接口的 ifIndex
index=$(snmpwalk -IR localhost RFC1213-MIB::ifDescr |grep eth0|cut -d '=' -f 1|cut -d '.' -f 2)
# 再通过 snmp 协议取得 ififInOctets 和 ifOutOctets 的值
# 由于在 /etc/snmp.conf 中配置了 defVersion 和 defCommunity ,所以 snmpget 命令不用指定这两个参数
eth0_in=$(snmpget -IR -Os localhost ifInOctets.${index}|cut -d ':' -f 2|tr -d '[:blank:]')
eth0_out=$(snmpget -IR -Os localhost ifOutOctets.${index}|cut -d ':' -f 2 |tr -d '[:blank:]')
echo $eth0_in
echo $eth0_out
[root@dns1 bob]#
[root@dns1 bob]# cat get_lo_traffic.sh
#!/bin/bash
# 首先取得 eth0 接口的 ifIndex
index=$(snmpwalk -IR localhost RFC1213-MIB::ifDescr |grep lo|cut -d '=' -f 1|cut -d '.' -f 2)
lo_in=$(snmpget -IR -Os localhost ifInOctets.${index}|cut -d ':' -f 2|tr -d '[:blank:]')
lo_out=$(snmpget -IR -Os localhost ifOutOctets.${index}|cut -d ':' -f 2 |tr -d '[:blank:]')
echo $lo_in
echo $lo_out
[root@dns1 bob]#
再把这2个脚本放入 crontab 中,每5分钟执行一次
*/5 * * * * /home/bob/get_eth0_traffic.sh
*/5 * * * * /home/bob/get_lo_traffic.sh
不过这样会有讨厌的邮件产生,也可以在脚本中用 while true 循环,配合 sleep 300 让脚本一直运行,而不是重复启动脚本。具体选择那样你自己决定。
当所有的准备工作都完成后,就可以开始考虑建库了。
--------------------------------------------------------------------------------
ailms 回复于:2006-12-04 09:22:46
建立 RRD 数据库
[color=blue]
**********************************************************************************************************************
注 :该教程参考了如下内容 :
A)官方文档 :
B)abel 兄的大作 :
作者 :ailms <>
版本 :v1
最后修改 :2006/11/17 17:35
**********************************************************************************************************************
[/color]
准备工作都做完了,脚本也写完了,就可以开始建库了。建库实际上就是建立后缀名为 .rrd 的 RRD 文件。
[size=4]一)语法格式[/size]
rrdtool create filename [--start|-b start time] [--step|-s step]
[DS:ds-name:DST:dst arguments]
[RRA:CF:cf arguments]
其中 filename 、DS 部分和 RRA 部分是必须的。其他两个参数可免。
[size=4]二)参数解释[/size]
A) :默认是以 .rrd 结尾,但也以随你设定。
B) --step :就是 RRDtool “期望” 每隔多长时间就收到一个值。和 MRTG 的 interval 同样含义。默认是5分钟。我们的脚本也应该是
每5分钟运行一次。
C) --start :给出 RRDtool 的第一个记录的起始时间。RRDtool 不会接受任何采样时间小于或者等于指定时间的数据。也就是说 –-start
指定了数据库最早的那个记录是从什么时候开始的。如果 update 操作中给出的时间在 –-start 之前,则 RRDtool拒绝接受。--satrt 选项也是
可选的。按照 我们在前一篇中的设定,则默认是当前时间减去 600*300秒,也就是50个小时前。 如果你想指定--start 为1天前,可以用
--start $(date -d '1 days aog' +%s)
注意,--start 选项的值必须是 timestamp 的格式。
D) DS :DS 用于定义 Data Soure 。也就是用于存放脚本的结果的变量名(DSN)。
就是我们前面提到的 eth0_in ,eth0_out, lo_in , lo_out 。DSN 从 1-19 个字符,必须是 0-9,a-z,A-Z 。
E) DST :DST 就是 Data Source Type 的意思。有 COUNTER、GUAGE、DERIVE、ABSOLUTE、COMPUTE 5种。
由于网卡流量属于计数器型,所以这里应该为 COUNTER 。
F) RRA :RRA 用于指定数据如何存放。我们可以把一个RRA 看成一个表,各保存不同 interval 的统计结果
G)PDP :Primary Data Point 。正常情况下每个 interval RRDtool 都会收到一个值;RRDtool 在收到脚本给来的值后 会计算出另外
一个值(例如平均值),这个 值就是 PDP ;这个值代表的一般是“xxx/秒”的含义。注意,该值不一定等于RRDtool 收到的那个值。除非是
GAUGE ,可以看下面的例子就知道了
H) CF :CF 就是 Consolidation Function 的缩写。也就是合并(统计)功能。有 AVERAGE、MAX、MIN、LAST 四种
分别表示对多个PDP 进行取平均、取最大值、取最小值、取当前值四种类型。具体作用等到 update 操作时 再说。
I) CDP :Consolidation Data Point 。RRDtool 使用多个 PDP 合并为(计算出)一个 CDP。也就是执行上面 的CF 操作后的结果。这个值就是存入 RRA
的数据,绘图时使用的也是这些数据。
[size=4] 三)再说 DST [/size]
DST 的选择是十分重要的,如果选错了 DST ,即使你的脚本取的数据是对的,放入 RRDtool 后也是错误的,更不用提画出来的图是否有意义了。
如何选择 DST 看下面的描述 :
A)COUNTER :必须是递增的,除非是计数器溢出(overflows)。在这种情况下,RRDtool 会自动修改收到的值。例如网络接口流量、收到的
packets 数量都属于这一类型。
B)DERIVE:和 COUNTER 类似。但可以是递增,也可以递减,或者一会增加一会儿减少。
C)ABSOLUTE :ABSOLUTE 比较特殊,它每次都假定前一个interval的值是0,再计算平均值。
D)GAUGE :GAGUE 和上面三种不同,它没有“平均”的概念,RRDtool 收到值之后字节存入 RRA 中
E)COMPUTE :COMPUTE 比较特殊,它并不接受输入,它的定义是一个表达式,能够引用其他DS并自动计算出某个值。例如
DS:eth0_bytes:COUNTER:600:0:U DS:eth0_bits:COMPUTE:bytes,8,*
则 eth0_bytes 每得到一个值,eth0_bits 会自动计算出它的值:将 eth0_bytes 的值乘以 8 。不过 COMPUTE 型的 DS 有个限制,只能应用
它所在的 RRD 的 DS ,不能引用其他 RRD 的 DS。 COMPUTE 型 DS 是新版本的 RRDtool 才有的,你也可以用 CDEF 来实现该功能。
F)AVERAGE 类型适合于看“平均”情况,例如一天的平均流量,。所以 AVERAGE 适用于需要知道 ‘xxx/秒’ 这样的需求。但采用 AVERAGE 型时,你并不知道
在每个 CDP 中(假设30分钟平均,6个PDP组成)之中,流量具体是如何变化的,什么时候高,什么时候低。这于需要用到别的统计类型了
G)MAXIMUM 、MINIMUM不适用想知道“xxx/秒”这样的需求,而是适用于想知道某个对象在各个不同时刻的表现的需求,也就是着重点在于各个时间点。
也就是所谓的“趋势”了,还是上面的例子,如果采用 MAXIMUM 或者 MINIMUM 的 CF ,可以看出接口在每个 CDP 的周期内最高是达到多少,最低又是多
少,如果是 AVERAGE 的话,有可能前5个 PDP 都很均匀,但最后一个 PDP 的值发生很大的突变。这时候如果用 AVERAGE 可能是看不出来的,因为突变的部
分被平均分配到整个时间段内了,所以看不出突变这一现象;但如果用 MAXIMUM 就可以清楚的知道在该 CDP 的周期内,曾经有达到某个值的时候。所以用
MAXIMUM 或者 MINIMUM 就可以知道某个对象在某个时间段内最大达到多少,最低低到什么程度。
例如要看某个接口在一天内有没有超过50Mb 流量的时候就要用 MAXIMUM
例如要看磁盘空间的空闲率在一天内有没有低于 20% 的时候就要用 MINIMUM
H)LAST 类型适用于 “累计”的概念,例如从xxx时候到目前共累计xxxx 这样的需求。例如邮件数量,可以用 LAST 来表示 30 分钟内总共收到多少个邮件,同
样 LAST 也没有平均的概念,也就是说不适用于 ‘xxx/秒’ 这样的需求,例如你不能说平均每秒钟多少封邮件这样的说法;同样也不适用于看每个周期内的变化,
例如30分钟内共收到100封邮件,分别是 :第一个5分钟20封,第二个5分钟30封,第三个5分钟没有,第4个5分钟10封,第5个5分钟也没有,第6个5分钟
40封。如果用 MAXIMUM 或者 MINIMUM 就不知道在30分钟内共收到100封邮件,而是得出30和0。所以 LAST 适用于每隔一段时间被观察 对象就会复位的
情况。例如每30分钟就收一次邮件,邮件数量就是 LAST 值,同时现有的新邮件数量就被清零;到下一个30分钟再收一次邮件,又得到一个 30 分钟的 LAST 值。
这样就可以得得出“距离上一次操作后到目前为止共xxx”的需求。(例如距离上一次收取邮件后又共收到100封新邮件)
[size=4] 四)DST 实例说明[/size]
这样说可能还是比较模糊,可以看下面的例子,体会一下什么是 DST 和 PDP :
引用:
Values = 300, 600, 900, 1200 # 假设 RRDtool 收到4个值,分别是300,600,900,1200
Step = 300 seconds # step 为 300
COUNTER = 1,1, 1,1 # (300-0)/300,(600-300)/300,(900-600)/300,(1200-900)/300 ,所以结果为 1,1,1,1
DERIVE = 1,1,1,1 # 同上
ABSOLUTE = 1,2,3,4 # (300-0)/300,(600-0)/300 , (900-0)/300, (1200-0)/300,所以结果为 1,2,3,4
GAUGE = 300,600,900,1200 # 300 , 600 ,900 ,1200 不做运算,直接存入数据库
所以第一行的 values 并不是 PDP ,后面4行才是 PDP
[size=4] 五)开始建库[/size]
[root@dns1 root]# rrdtool create eth0.rrd \
> --start $(date –d ‘1 days ago’ +%s) \
> --step 300 \
> DS:eth0_in:COUNTER:600:0:12500000 \ # 600 是 heartbeat;0 是最小值;12500000 表示最大值;
> DS:eth0_out:COUNER:600:0:12500000 \ # 如果没有最小值/最大值,可以用 U 代替,例如 U:U
> RRA:AVERAGE:0.5:1:600 \ # 1 表示对1个 PDP 取平均。实际上就等于 PDP 的值
> RRA:AVERAGE:0.5:4:600 \ # 4 表示每4个 PDP 合成为一个 CDP,也就是20分钟。方法是对4个PDP取平均,
> RRA:AVERAGE:0.5:24:600 \ # 同上,但改为24个,也就是24*5=120分钟=2小时。
> RRA:AVERAGE:0.5:288:730 # 同上,但改为288个,也就是 288*5=1440分钟=1天
[root@dns1 root]#
检查一下结果
bob]# ll -h eth0.rrd
-rw-r--r-- 1 root root 41K 11月 19 23:16 eth0.rrd
[root@dns1 bob]#
有的人可能会问,上面有两个 DS,那 RRA 中究竟存的是那个 DS 的数据呢?实际上,这些 RRA 是共用的,你只需建立一个 RRA,它就可以用于全部的 DS 。
所以在定义 RRA 时不需要指定是给那个 DS 用的。
[size=4]六)什么是 CF [/size]
以第2个RRA 和 4,2,1,3 这4个 PDP 为例
AVERAGE :则结果为 (4+2+1+3)/4=2.5
MAX :结果为4个数中的最大值 4
MIN :结果为4个数中的最小值1
LAST :结果为4个数中的最后一个 3
同理,第三个RRA和第4个RRA则是每24个 PDP、每288个 PDP 合成为1个 CDP
[size=4] 七)解释度(Resolution)[/size]
这里要提到一个 Resolution 的概念,在官方文档中多处提到 resolution 一词。Resolution 究竟是什么?Resolutino 有什么用?
举个例子,如果我们要绘制1小时的数据,也就是60分钟,那么我们可以从第一个RRA 中取出12个 CDP 来绘图;也可以从第2个 RRA
中取出2个 CDP 来绘图。到底 RRDtool 会使用那个呢?
让我们看一下 RRA 的定义 :RRA:AVERAGE:0.5:4:600 。
Resolution 就等于 4 * step = 4 * 300 = 1200 ,也就是说 ,resolution 是每个CDP 所代表的时间范围,或者说 RRA 中每个 CDP(记录)
之间的时间间隔。所以第一个 RRA 的 resolution 是 1* step=300,第2是 1200,第三个是 24*300=7200,第4个 RRA 是 86400 。
默认情况下,RRDtool 会自动挑选合适的 resolution 的那个 RRA 的数据来绘图。我们大可不必关心它。但如果自己想取特定 RRA 的数据,就需要用到它了。
关于 Resolution 我们还会在 fetch 和 graph 操作中提到它。
[size=4]八)xff 字段[/size]
细心的朋友可能会发现,在 RRA 的定义中有一个数值,固定是 0.5 ,这个到底是什么东东呢?
这个称为 xff 字段,是 xfile factor 的缩写。让我们来看它的定义 :
引用:
The xfiles factor defines what part of a consolidation interval may be made up from *UNKNOWN* data while
the consolidated value is still regarded as known. It is given as the ratio of allowed *UNKNOWN* PDPs to
the number of PDPs in the interval. Thus, it ranges from 0 to 1 (exclusive)
这个看起来有点头晕,我们举个简单的例子 :例如
RRA:AVERAGE:0.5:24:600
这个 RRA 中,每24个 PDP (共两小时)就合成为一个 CDP,如果这 24 个 PDP 中有部分值是 UNKNOWN (原因可以很多),例如1个,那么这个 CDP
合成的结果如何呢?是否就为 UNKNOWN 呢?
不是的,这要看 xff 字段而定。Xff 字段实际就是一个比例值。0.5 表示一个 CDP 中的所有 PDP 如果超过一半的值为 UNKNOWN ,则该 CDP 的值就被标为
UNKNOWN。也就是说,如果24个 PDP中有12个或者超过12个 PDP 的值是 UNKNOWN ,则该 CPD 就无法合成,或者合成的结果为 UNKNOWN;
如果是11个 PDP 的值为 UNKNOWN ,则该 CDP 的值等于剩下 13 个 PDP 的平均值。
如果一个 CDP 是有2个 PDP 组成,xff 为 0.5 ,那么只要有一个 PDP 为 UNKNOWN ,则该 PDP 所对应的 CDP 的值就是 UNKNOWN 了
--------------------------------------------------------------------------------
ailms 回复于:2006-12-04 09:23:47
RRDtool简体中文教程_5:如何获取RRD文件的信息
获取 RRD 文件的信息
[color=blue]
**********************************************************************************************************************
注 :该教程参考了如下内容 :
A)官方文档 :
B)abel 兄的大作 :
作者 :ailms <>
版本 :v1
最后修改 :2006/11/17 17:35
**********************************************************************************************************************
[/color]
[size=4] 一)前言[/size]
可能你已经颇不亟待的想知道如何往 RRD 文件插入数据、如何绘图了吧?hoho,先别急,在你做这些事情之前,最好先思考以下几个问题 :
A)如果给你一个 RRD 文件,你能知道它的第一次/最后一次 update 的时间是在什么时候吗?
B)如果你很久之前建立了一个 RRD 文件,现在因为工作原因需要对该 RRD 文件进行一些修改。不过遗憾的是,
你已经不记得得当初设置的具体选项和参数了, 这时候该怎么办呢?
这两个问题就对应今天要讲的两个操作 :first/last 、info 。
first 就是用于查看该 RRD 文件中某个 RRA 的第一个数据是在什么时候插入的(或者说第一次更新);
last 就是查看该 RRD 文件的最近一次更新;
info就是查看 rrd 文件的结构信息。
下面就以实际例子来看一下该怎么用这三个命令 :
[size=4]二)如何查询一个 RRD 文件的结构信息[/size]
[root@dns1 bob]# rrdtool info eth0.rrd (由于输出信息较多,截取了一部分)
filename = "eth0.rrd"
rrd_version = "0003"
step = 300 # RRDtool 希望每5分钟收到一个数据
last_update = 1163862985 # 这是最近一次更新的 timestamp 。可以用 date 转换为具体的时间
ds[eth0_in].type = "COUNTER" # 有一个名为 eth0_in 的 DS,DST是 COUNTER
ds[eth0_in].minimal_heartbeat = 600 # hearbeat 时间是600 秒
ds[eth0_in].min = 0.0000000000e+00 # eth0_in 的最小值是 0 (bytes)
ds[eth0_in].max = 1.2500000000e+07 # eth0_in 的最大值是 1250000000 (bytes)
ds[eth0_in].last_ds = "UNKN"
ds[eth0_in].value = 0.0000000000e+00
ds[eth0_in].unknown_sec = 85
ds[eth0_out].type = "COUNTER"
ds[eth0_out].minimal_heartbeat = 600
ds[eth0_out].min = 0.0000000000e+00
ds[eth0_out].max = 1.2500000000e+07
ds[eth0_out].last_ds = "UNKN"
ds[eth0_out].value = 0.0000000000e+00
ds[eth0_out].unknown_sec = 85
rra[0].cf = "AVERAGE" # 第一个 RRA 的编号是0,不是1。
rra[0].rows = 600 # 共保存 600 个记录
rra[0].pdp_per_row = 1 # 每个 CDP 由一个 PDP 统计得出
rra[0].xff = 5.0000000000e-01 # 只要当前interval 的 PDP 为 unknown ,则该 CDP 的值也是unknown
rra[0].cdp_prep[0].value = NaN
rra[0].cdp_prep[0].unknown_datapoints = 0
rra[0].cdp_prep[1].value = NaN
rra[0].cdp_prep[1].unknown_datapoints = 0
rra[1].cf = "AVERAGE" # 第二个 RRA 的编号是 1。同样也是 AVERAGE 型。
rra[1].rows = 600 # 也是保存 600 个记录
rra[1].pdp_per_row = 4 # 每个 CDP 由4个 PDP 的求平均值得出
rra[1].xff = 5.0000000000e-01 # 每个 CDP 最多允许2个 PDP 为 unknown ,超过则该 CDP 为unknown
rra[1].cdp_prep[0].value = NaN
rra[1].cdp_prep[0].unknown_datapoints = 3
rra[1].cdp_prep[1].value = NaN
rra[1].cdp_prep[1].unknown_datapoints = 3
[root@dns1 bob]#
[color=red]由于信息太长,这里截取了后面2个 RRA 的信息。[/color]
[size=4]三)第一次更新/最近一次更新[/size]
如果想知道最近一次更新发生在什么时候,除了可以用上面的 info 操作,还可以用 last 操作
[root@dns1 bob]# rrdtool last eth0.rrd
1163862985
[root@dns1 bob]#
如果转换成具体的时间就是 :
[root@dns1 bob]# rrdtool last eth0.rrd |xargs -i date -d '1970-01-01 {} sec utc'
六 11月 18 23:16:25 CST 2006
[root@dns1 bob]#
[root@dns1 bob]# rrdtool first eth0.rrd
1163683200
[root@dns1 bob]#
如果换成具体的时间就是 :
[root@dns1 bob]# [root@dns1 bob]# rrdtool first eth0.rrd |xargs -i date -d '1970-01-01 {} sec utc'
四 11月 16 21:20:00 CST 2006
[root@dns1 bob]#
这三个命令的语法都非常简单,但并不可以因此小看它们的功能,尤其是 info 操作。日后如果需要对 RRD 文件进行调整,是经常需要用到的。
--------------------------------------------------------------------------------
ailms 回复于:2006-12-04 09:24:20
更新 RRD 文件
[color=blue]
**********************************************************************************************************************
注 :该教程参考了如下内容 :
A)官方文档 :
B)abel 兄的大作 :
作者 :ailms <>
版本 :v1
最后修改 :2006/11/17 17:35
**********************************************************************************************************************
[/color]
[size=4]一)前言[/size]
写了N多东东,总算到了 update 部分了。这里有必要比较一下 RRDtool 和 MRTG 在 update 方面的差别。
A)MRTG 可以通过 SNMP 协议直接访问 SNMP 对象,你只需要在 cfg 文件中的 Target 指定 OID ,MRTG 就可以自动替你取回数据。
例如Target[as1_eth0]: 2:n7css@172.17.64.11:::::1 ,表示使用 SNMP v1 协议访问 172.17.64.11 主机上 index 为 2 的那个接口,
默认是取 ifInOctets 和 ifOutOctets 这两个对象的值。RRDtool 则没有这个功能,只能你自己写脚本取数据。
B)MRTG 只支持 COUNTER 和 GAUGE 类型的 Target ;RRDtool 则还可以使用 DERIVE、ABSOLUTE、COMPUTE
C)由于上面的原因,MRTG 无法识别小数,负数。例如你给 MRTG 一个 -1 的值,它会解释为 1 ;这点可以通过 LOG 看出来。
小数也不行。例如 .72 (bc 的输出)会被识别为 72 ,而不是 0.72。
D)MRTG 每次 update 每次运行只更新一次,或者说只插入一行记录。但 RRDtool 可以在一个 updat操作中插入多个记录。
E)MRTG 一次要求2个值,RRDtool 则没有该方面的限制。
F)最大的一个区别是, MRTG 在收到一个值后会自动得出 timestamp ,并记录在 log 的第一个字段;而 RRDtool 是需要你给出一个 timestamp ,
表示该数据是什么时间采集的。
[size=4]二)update 操作的语法格式[/size]
rrdtool {update | updatev} filename
[--template|-t ds-name[:ds-name]...]
N|timestamp:value[:value...]
...]
[timestamp:value[:value...] ...]
N 表示 now 的意思,会被 RRDtool 替换为当前的 timestamp ,也就是 date +%s 的结果。Timestamp 部分比较灵活,可以是数字形式,也可以是
AT-风格的时间(参考 at 命令的 manual),有点类似于自然语言的风格。
[size=4]三)手工方式 update 数据库[/size]
我们先学习一下如何手工 update 数据库。Update 命令分成两部分 :
A)时间戳 (timestamp):表示该数据是在那个时间点采集的。Timestamp 的格式可以非常灵活 :
数字形式 :例如1164419418 ,表示 “六 11月 25 09:50:18 CST 2006”。通常用于手工插入的方式。
快捷方式 :N 。字母N 表示当前时间(Now)。如果是通过 crontab 的方式来运行 update 操作,这是最实用的方式。
AT-风格 :所谓的 AT 风格的时间,可以参考 at 命令的 manual。例如 now、yesterday、now-1hour、now+5min 都是 AT风格的时间。
要注意的是,如果使用 AT风格的时间,则时间和第一个value之间使用 @ 分隔,而不是 “:”
B)数值部分 :一个 RRD 文件可以有多个 DS ,所以一次 update 可以给出多个 value 。多个 value 之间用 “:” 分隔。不过是不是所有的 DS 都必须
给出值呢?不一定。有时候你只想给出一部分 DS 的值,甚至有时候某些类型的 DS 是不允许赋值的,例如 COMPUTE 型的 DS 就是这样一个例子。
[size=4]四)实际操作[/size]
实例一 :一个错误的例子
[root@dns1 bob]# rrdtool update eth0.rrd 1163862980:1:2
ERROR: illegal attempt to update using time 0 when last update time is 1163862985 (minimum one second step)
[root@dns1 bob]#
咦?为什么出错了呢?是语法错误吗?不是的,RRDtool 提示最近一次更新是在1163862985 这个时候。也就是说,update 给出的时间戳必须大于该值。
不能等于或者小于该时刻。因为数据一旦插入到 RRA 中,就不允许再次修改。所以 update 会检查给出的时间戳是否大于最后一次更新的时间戳,如果不是
则报错,不予执行。那如何才能知道最近一次更新的时间戳呢?还记得前一篇“如何获取RRD文件的信息”中介绍的 last 和 info 命令吗?对了!就是它们。
执行一下看看是什么结果 ?
[root@dns1 bob]# rrdtool last eth0.rrd
1163862985
[root@dns1 bob]#
last 操作显示的时间戳和上面的报错信息给出的值一样。这个时间是
[root@dns1 bob]# date -d '1970-01-01 1163862985 sec utc'
六 11月 18 23:16:25 CST 2006
[root@dns1 bob]#
总之如果要 update 数据库,则 update 操作给出的时间戳必须晚于最后一次 update 的时间。
实例二 :还是一个错误的例子
我们挑 23:16的下一个5分钟23:20作为时间戳吧。
[root@dns1 bob]# date -d '2006-11-18 23:20' +%s
1163863200
[root@dns1 bob]#
所以 update 命令为 :
[root@dns1 bob]# rrdtool update eth0.rrd 1163863200:1
ERROR: expected 2 data source readings (got 1) from 1163863200:1:...
[root@dns1 bob]#
还是不行?!!
仔细看错误信息,原来是我们给少了一个值。还记得 info 命令吗?这会儿它派上用场了。
[root@dns1 bob]# rrdtool info eth0.rrd
filename = "eth0.rrd"
…..(省略)
last_update = 1163862985
ds[eth0_in].type = "COUNTER"
ds[eth0_out].type = "COUNTER"
原来是2个 DS ,怪不得 RRDtool 会报错了
实例三 :这次应该成功了吧?
[root@dns1 bob]# rrdtool update eth0.rrd 1163863200:1:2
[root@dns1 bob]#
这会倒是没有错误信息,那究竟数据是否别插入到 RRA 中了呢?
对于该问题,有两个方法,一个是通过 fetch 操作,从 RRA 中提取数据;但这个我们下一篇再讲。
还有一种方法就是用 updatev 操作来代替 update 。updatev 的 v 表示 verbose 的意思,现在就来看 updatev 的作用 :
实例四 :updatev 的好处
我们执行多个 update 操作
[root@dns1 bob]# rrdtool last eth0.rrd
1163864400
[root@dns1 bob]#
[root@dns1 bob]# rrdtool update eth0.rrd 1163864700:3000:4000
[root@dns1 bob]# rrdtool updatev eth0.rrd 1163865000:3300:4600
return_value = 0
[1163865000]RRA[AVERAGE][1]DS[eth0_in] = 1.0000000000e+00
[1163865000]RRA[AVERAGE][1]DS[eth0_out] = 2.0000000000e+00
可以看到 return value 是 0,这个 return value 你可以理解为 shell 编程中的 exit status 。updatev用 0 表示成功,-1 表示失败。
不过我们插入的值明明是 3300 和 4600 ,为什么出来的结果是 1和2 呢?
这是因为 eth0_in 和 eth0_out 都是 COUNTER 型的 DS,所以 RRDtool 在收到 3300 和 4600 后,会作一个运算,就是
(3300-3000)/ step (300)= 1,(4600-4000)/step(300)=2 ,这就是 1和 2 这两个值的来源了。还记得前面提到的 PDP 吗?
这两个值 (1 和2)就是 PDP 了,而不是 3300 和 4600 。这点要搞清楚。
实例五 :另外一个 updatev 的例子
[root@dns1 bob]#
[root@dns1 bob]# rrdtool updatev eth0.rrd 1163865300:3300:4600
return_value = 0
[1163865300]RRA[AVERAGE][1]DS[eth0_in] = 0.0000000000e+00
[1163865300]RRA[AVERAGE][1]DS[eth0_out] = 0.0000000000e+00
[root@dns1 bob]#
在1163865300 这个时刻我们给出的值和上次一样,所以 eth0_in 和 eth0_out 的 PDP 都为 0
搞清楚了 PDP 的概念,现在我们来看什么是 CDP ,以及 CDP 是如何计算的
实例六 :通过 updatev 掌握 CF 的概念
[root@dns1 bob]# rrdtool updatev eth0.rrd 1163865600:4000:5000
return_value = 0
[1163865600]RRA[AVERAGE][1]DS[eth0_in] = 2.3333333333e+00
[1163865600]RRA[AVERAGE][1]DS[eth0_out] = 1.3333333333e+00
[1163865600]RRA[AVERAGE][4]DS[eth0_in] = 1.6666666667e+00
[1163865600]RRA[AVERAGE][4]DS[eth0_out] = 1.6666666667e+00
[1163865600]RRA[AVERAGE][24]DS[eth0_in] = NaN
[1163865600]RRA[AVERAGE][24]DS[eth0_out] = NaN
[root@dns1 bob]#
这次的输出和上次又不一样了。这次 update 操作影响到几个 RRA ,看到 [] 中的 1,4,24 了吗?它们就是代表不同的 RRA 中每个 CDP 所包含的 PDP 数量。
1 就是 1个 CDP 包含1 个 PDP,4 就是 一个 CDP 包含4个 PDP(20分钟)、24 就是 一个 CDP 包含24个 PDP(2小时)。
不过为什么没有 288 呢?eth0.rrd 的第4个 RRA 不是规定每288个 PDP 合并为一个 CDP 吗?
因为这个时候还轮不到它出场。1163865600 / 7200 = 161648 , 也就是说刚好1163865600 是在 7200 的某个周期上(161648)。
但1163865600 / 86400 ≈ 13470.66 ,说明1163865600 还不到 86400 的周期。
必须等到13471* 86400=1163894400 才会出现 [288] 的 CDP,那这个时间戳代表的时间是什么时候呢?看下面的 date 命令就知道了 :
[root@dns1 bob]# date -d '1970-01-01 1163894400 sec utc'
日 11月 19 08:00:00 CST 2006
[root@dns1 bob]#
[root@dns1 root]# date -d '1970-01-01 1163865600 sec utc'
日 11月 19 00:00:00 CST 2006
[root@dns1 root]#
这样不就是刚好相差1天的时间了吗?你可能会觉得很奇怪,为什么不是00:00 而是 08:00呢?
还记得create 操作的语法吗?其中有一个 –-start 参数吗?不记得了?没关系,那就得用 first 操作来重新找出来,
[root@dns1 bob]# rrdtool first eth0.rrd --rraindex 3
1100822400
[root@dns1 bob]#
[root@dns1 bob]# date -d '1970-01-01 1100822400 sec utc'
五 11月 19 08:00:00 CST 2004
[root@dns1 bob]#
看到了吗?是 2004 年的 11 月19日早上8点正,距离 2006-11-19 刚好是2年,也就是 730 天,因为 eth0.rrd 的第4个RRA
只保存730个记录。每个记录时间上相差1天。也就是第一个记录是 2004/11/19 8:00 ,第二个记录是 2004/11/20 8:00 ,
第三个记录代表 2004/11/21 8:00 ,依次类推。所以离1163865600 最近的下一个记录是发生在 2006/11/19 8:00 。
所以严格意义上来说,RRDtool 中的一天并不一定是从 0:00 开始的,但可以保证的就是两个记录之间肯定相差86400秒(1天)。
[size=4]四)自动更新数据库[/size]
其实这些都只不过是手工 update 时需要注意的一些地方,如果是自动更新数据库,时间戳方面就交给 RRDtool 去处理吧,我们不用操心了。
前面我们已经写好了一个脚本,现在就用它来更新
[root@dns1 bob]# cat get_eth0_traffic.sh
#!/bin/bash
# 首先取得 eth0 接口的 ifIndex
index=$(snmpwalk -IR localhost RFC1213-MIB::ifDescr |grep eth0|cut -d '=' -f 1|cut -d '.' -f 2)
# 再通过 snmp 协议取得 ififInOctets 和 ifOutOctets 的值
# 由于在 /etc/snmp.conf 中配置了 defVersion 和 defCommunity ,所以 snmpget 命令不用指定这两个参数
eth0_in=$(snmpget -IR -Os localhost ifInOctets.${index}|cut -d ':' -f 2|tr -d '[:blank:]')
eth0_out=$(snmpget -IR -Os localhost ifOutOctets.${index}|cut -d ':' -f 2 |tr -d '[:blank:]')
echo ${eth0_in}
echo ${eth0_out}
# 需要我要用这些数据来更新 eth0.rrd ,注意 update 时的 timestamp 我们用的是 N
/usr/local/rrdtool-1.2.14/bin/rrdtool updatev /home/bob/eth0.rrd N:${eth0_in}:${eth0_out}
[root@dns1 bob]#
[size=4]五)接下来是什么呢?[/size]
有了数据,下面该学什么了呢?是绘图吗?
不是!^_^!! (估计有人快疯了吧)
在绘图之前,你有没有想过 RRDtool 在绘图时如何取数据的呢?
例如我想画2小时内的数据,那么我们有4个 RRA ,其 resolution 分别是 300,1200,7200,86400
(还记得什么是 resolution 吗?就是每个 RRA 中两个 CDP 相隔的时间)。是从第一个 RRA 取出 7200/300=24 个记录,
还是从第二个 RRA 取出 7200/1200=6 个记录呢?或者是从第三个 RRA 中取出1个记录就可以呢?
这些问题我们就留待下一篇再学习吧。这里给大家留几个问题 :
[color=red]
引用:
A) 如果 eth0.rrd 在5分钟内收到不止1个更新,结果会怎样?提示:用 updatev 就可以看出来了
B) 如果过了 eth0.rrd 在5分钟内没有收到脚本返回的值,是否立即就用 UNKNOWN 作为 PDP 的值?
C) 参考上面的例子,搞清楚 heartbeat 的含义
D) 在搞清楚 heartbeat 后,再想一下 heartbeat 和 step 之间的关系。
[/color]
--------------------------------------------------------------------------------
ailms 回复于:2006-12-04 09:25:08
从 RRD 文件中提取数据
[color=blue]
**********************************************************************************************************************
注 :该教程参考了如下内容 :
A)官方文档 :
B)abel 兄的大作 :
作者 :ailms <>
版本 :v1
最后修改 :2006/11/17 17:35
**********************************************************************************************************************
[/color]
[size=4]一)前言[/size]
RRD 是 Round Robin Database 的意思,那么是否可以象普通的数据库进行查询操作呢?
答案是可以的。fetch 就是用来做这种事情的工具。当然 fetch 不能和 select 语句相比,它只是根据用户指定的时间,
从合适的 RRA 中取出数据,并加以格式化。不过和 MRTG 相比,已经好很多了,至少你不用取看该死的 log 文件。
实际上,fetch 操作其实可以不学,因为 RRDtool 会自动帮你选好数据。但你如何确定 RRDtool 取的数据就是你想要的呢?
或者说你如何证明 RRDtool 绘制出来的图是正确的呢?
废话少说,下面开始正文
[size=4]二)fetch 操作的语法[/size]
rrdtool fetch filename CF [--resolution|-r resolution] [--start|-s start] [--end|-e end]
其中 --start、--end、-r 都是可选的 。RRDtool 默认的 --end 是 now ,--start 是 end-1day ,也就是1天前。
CF 可以是 AVERAGE、MAX、MIN、LAST ,当然必须建库时有该 CF 类型的 RRA 才可以查,否则会报错。
[size=4]三)fetch 如何取数据[/size]
在确定了时间范围后,RRDtool 会从多个 RRA 中挑选最佳的那个 RRA 的数据。至于什么是“最佳”,则从两个方面考虑 :
A)[color=blue]第一是该 RRA 的数据要尽可能的覆盖所请求的时间范围。[/color]如何计算一个 RRA 的覆盖时间呢?以 eth0.rrd 的第一个RRA 为例,
有 600 个记录,每个记录相隔300秒,则总的时间覆盖范围是180000 秒≈2天,所以如果 –-start 和 -–end 规定的时间范围
大于2天,则 RRDtool 不会从该 RRA 中取数据。
B)[color=blue]第二是 resolution 的要求。[/color]还是上面的例子,如果是要画3天的数据,从时间覆盖范围上来讲,第2、3、4 个 RRA 都符合要求。
那究竟挑选那个 RRA 的数据呢?如果 fetch 中有指定 –r 选项,则挑选 resolution 等于 –r 指定的值那个 RRA 的数据。如果没有
–r 选项,则从第一个合适的 RRA 中取数据。
C)fetch 如果不加 –-start、--end、-r ,则默认输出 resolution 最小的那个 RRA 的数据。就像下面的例子1一样。
[size=4]四)实际例子[/size]
实例一 :默认情况
[root@dns1 bob]# rrdtool fetch eth0.rrd AVERAGE |more
eth0_in eth0_out
1164467700: 1.1337243905e+01 9.6323712631e-02
1164468000: 1.7896453039e+01 0.0000000000e+00
1164468300: 1.8469136234e+01 1.2215723119e+00
。。。。(中间省略)
1164553800: 6.9634610564e+01 4.9644415243e+01
1164554100: nan nan
[root@dns1 bob]# date (当前时间)
日 11月 26 23:11:12 CST 2006
[root@dns1 bob]# date -d '1970-1-1 1164554100 sec utc' (最后一个记录的时间)
日 11月 26 23:15:00 CST 2006
[root@dns1 bob]#
[root@dns1 bob]# date -d '1970-1-1 1164467700 sec utc' (第一个记录的时间)
六 11月 25 23:15:00 CST 2006
[root@dns1 bob]#
fetch 输出的第一列是 timestamp ,表示后面的数据是在什么时间收到的。”:” 后面就是DS的值。fetch 不能指定只取那个 DS 的数据,
只能一次性取出全部 DS 的值。可以看到,eth0.rrd 有两个 DS :eth0_in 和 eth0_out ,每个 DS 的值用 空格进行分隔,一律采用科学记数法的格式。
如果 fetch 不指定 –-start 和 -–end ,则默认取从当前时刻算起,往前1天的数据(289个记录)。因为现在是 23:11 ,还不到 23:15,所以最后一个记
录的值是 NaN (Not a Number),也就是 UNKNOWN 的意思。可以看到,两个记录之间的时间间隔是300。
实例二:使用 --start 和 --end 指定时间范围
[root@dns1 bob]# rrdtool fetch eth0.rrd AVERAGE --start 1164467700 --end 1164553800 |more
eth0_in eth0_out
1164468000: 1.7896453039e+01 0.0000000000e+00
1164468300: 1.8469136234e+01 1.2215723119e+00
1164468600: 1.5988336199e+01 1.4417769382e-01
。。。。。(中间省略很多)
1164553800: 6.9634610564e+01 4.9644415243e+01
1164554100: 1.7481962958e+02 2.3086574912e+02
[root@dns1 bob]#
可以看到第一个记录和最后一个记录都比 –-start 和 –-end 晚了300秒。
实例三 :使用 AT风格的时间
[root@dns1 bob]# rrdtool fetch eth0.rrd AVERAGE --start end-1day --end 1164553800 |more
eth0_in eth0_out
1164467700: 1.1337243905e+01 9.6323712631e-02
1164468000: 1.7896453039e+01 0.0000000000e+00
。。。。。。。(中间省略很多)
1164554100: 1.7481962958e+02 2.3086574912e+02
[root@dns1 bob]#
注意 --start 的值是 end-1day ,这就是 AT风格的时间。end 就是 --end 中给出的1164553800 。具体的时间范围是表示起始时间从1164553800 往前1天 。
可以看到,现在第一个记录和实例二相比,提前了300秒。和例2中的 –start 一致了。所以能够用 AT风格的时间的时候还是用 AT 风格的时间比较方便。
可以省去计算的麻烦,别人也比较容易看。