RRDTool
一 .RRDtool的定义
三.更新RRD文件
RRDtool定义
RRDtool 代表 “Round Robin Database tool” 。
所谓的“Round Robin” 其实是一种存储数据的方式,使用固定大小的空间来存储数据,并有一个指针指向最新的数据的位置。
我们可以把用于存储数据的数据库的空间看成一个圆,上面有很多刻度。这些刻度所在的位置就代表用于存储数据的地方。所谓指针,可以认为是从圆心指向这些刻度的一条直线。指针会随着数据的读写操作自动移动。
要注意的是,这个圆没有起点和终点,所以指针可以一直移动,而不用担心到达终点后就无法前进的问题。在一段时间后,当所有的空间都存满了数据,就又从头开始存放。这样整个存储空间的大小就是一个固定的数值。
所以RRDtool 就是使用类似的方式来存放数据的工具,RRDtool 所使用的数据库文件的后缀名是 ‘.rrd’。
官方站点位于http://oss.oetiker.ch/rrdtool/ 。
建立 RRD 数据库
语法格式
rrdtool create filename [--start|-b start time] [--step|-s step]
[DS:ds-name:DST:dst arguments]
[RRA:CF:cf arguments]
其中 filename 、DS 部分和 RRA 部分是必须的。其他两个参数可免。
A)<filename> :默认是以 .rrd 结尾,但也以随你设定。
B) --step :就是 RRDtool “期望” 每隔多长时间就收到一个值。默认是5分钟。
C) --start :這個 filename 的資料记录起始日期 ,以 1970 年至今的秒數 (預設是現在),给出 RRDtool 的第一个记录的起始时间。RRDtool 不会接受任何采样时间小于或者等于指定时间的数据。也就是说 –-start指定了数据库最早的那个记录是从什么时候开始的。如果 update 操作中给出的时间在 –-start 之前,则 RRDtool拒绝接受。
D) DS :DS 用于定义 Data Soure 。也就是用于存放脚本的结果的变量名(DSN)。
E) DST :DST 就是 Data Source Type 的意思。有 COUNTER、GUAGE、DERIVE、ABSOLUTE、COMPUTE 5种。
1)COUNTER :必须是递增的。
2)DERIVE:和 COUNTER 类似。但可以是递增,也可以递减,或者一会增加一会儿减少。
3)ABSOLUTE :ABSOLUTE 比较特殊,它每次都假定前一个interval的值是0,再计算平均值。
4)GAUGE :GAGUE 和上面三种不同,它没有“平均”的概念,RRDtool 收到值之后字节存入 RRA 中
5)COMPUTE :COMPUTE 比较特殊,它并不接受输入,它的定义是一个表达式,能够引用其他DS并自动计算出某个值。
例:
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
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 进行取平均、取最大值、取最小值、取当前值四种类型。
I) CDP :Consolidation Data Point 。RRDtool 使用多个 PDP 合并为(计算出)一个 CDP。也就是执行上面 的CF 操作后的结果。这个值就是存入 RRA的数据,绘图时使用的也是这些数据。
例:
/usr/local/rrdtool/bin/rrdtool create cpurand.rrd /
--start 1180627200 /
--step 300 /
DS:DATA1:GAUGE:300:0:1000 /
DS:DATA2:GAUGE:300:0:1000 /
DS:DATA3:GAUGE:300:0:1000 /
DS:DATA4:GAUGE:300:0:1000 /
DS:DATA5:GAUGE:300:0:1000 /
RRA:AVERAGE:0.5:1:8640 /
RRA:AVERAGE:0.5:2:8640
(0.5)-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 了
(300):
是有效期(heartbeat),如果連續如果原來在 12:00 要產生資料而沒有產生,前後 150 秒 (共300秒)的平均值會算成 12:00 的值,如果都沒有值,則會成為 "UNKNOWN"
(0:1000):
是說 DSN 的數值有效範圍,如果超出這個值,皆視為 UN,這裏也可以寫成 U:U 代表不限範圍
更新 RRD 文件
语法格式
rrdtool {update | updatev} filename
[--template|-t ds-name[:ds-name]...]
N|timestamp:value[:value...]
at-timestamp@value[:value...]
[timestamp:value[:value...] ...]
N 表示 now 的意思,会被 RRDtool 替换为当前的 timestamp。Timestamp 部分比较灵活,可以是数字形式,也可以是AT-风格的时间。
Update 命令分成两部分 :
A)时间戳 (timestamp)
表示该数据是在那个时间点采集的。Timestamp 的格式可以非常灵活 :
① 数字形式 :例如1164419418 ,表示 “六 11月 25 09:50:18 CST 2006”。通常用于手工插入的方式。
② 快捷方式 :N 。字母N 表示当前时间(Now)。
③ AT-风格 :所谓的 AT 风格的时间,可以参考 at 命令的 manual。例如 now、yesterday、now-1hour、now+5min 都是 AT风格的时间。要注意的是,如果使用 AT风格的时间,则时间和第一个value之间使用 @ 分隔,而不是 “:”
B)数值部分
一个 RRD 文件可以有多个 DS ,所以一次 update 可以给出多个 value 。多个 value 之间用 “:” 分隔。不过是不是所有的 DS 都必须给出值呢?不一定。有时候你只想给出一部分 DS 的值,甚至有时候某些类型的 DS 是不允许赋值的,例如 COMPUTE 型的 DS 就是这样一个例子。
例:
rrdtool update cpurand.rrd 1061811856:114:0:50:1199:0:821073
使用RRDtool 进行绘图
语法格式
rrdtool graph filename [option ...]
[data definition ...]
[data calculation ...]
[variable definition ...]
[graph element ...]
[print element ...]
其中的 data definiton、variable definition 、data calculation、分别是下面的格式
DEF:<vname>=<rrdfile>:<ds-name>:<CF>[:step=<step>][:start=<time>][:end=<time>][:reduce=<CF>]
VDEF:vname=RPN expression
CDEF:vname=RPN expression
其中 filename 就是你想要生成的图片文件的名称,默认是 png 。你可以通过选项修改图片的类型,可以有 PNG、SVG、EPS、PDF四种。
DEF 数据源,DEF 就是告诉 RRDtool 从那个 RRD 中取出指定DS
CDEF 一個虛擬的變數,其值為 DEF 的某些運算,其運算式需寫成後序
EX: a=1+3 寫成 a=1,3 +
http=(smtp+http+telnet)/1024 寫成 http=1024,smtp,http,telnet,+,+,/
LINE{1|2|3}:vname[#rrggbb[]]
LINE1:your_var#rgb顏色值:圖例說明,這個 "your_var" 需存在 DEF 或 CDEF 的宣告中,
AREA:vname[#rrggbb[]]
AREA 則是畫出資料數值至 0 之間的區磈圖
STACK:vname[#rrggbb[]]
STACK 則是表現在的圖的值,疊在上一個值上
时间范围控制(Time Range)
[-s|--start time] [-e|--end time] [-S|--step seconds]
起始/结束的时间。Graph 操作中有 –s ,-e 选项。这两个选项即可以用于控制图表的 X 轴显示的时间范围,也可以用于控制 RRDtool 从 RRA 中提取对应时间的数据。如果没有指定 –-end ,默认为 now;如果没有指定 –-start,则默认为1天前。如果两者都没有指定,则图表默认显示从当前算起1天内的。在DEF 中,也有 :start ,:end , :step ,这些和 –-start、--end、--step 之间的关系:
A) -S 选项可以直接控制 RRDtool 如何挑选 RRA 。如果 -S 和 :step 同时出现,则 :step 优先。
B) DEF 中的 :start 和 :end 可以覆盖 –-start 和 –-end 的值。默认情况下,如果 DEF 中不加 :start 和 :end ,则等于 –-start 和 –end。如果 DEF 中定义了 :start 和 :end ,则以 :start 和 :end 为准。
例:
① 使用 :start 和 :end 只显示指定时间内的数据
rrdtool graph1.png /
> --start now-1h / # X 轴显示1个小时的长度
> DEF:value1=eth0.rrd:eth0_in:AVERAGE:start=now-600:end=now-300 / # 但只取10分钟前到5分钟前的这部分
> AREA:value1#00ff00:in
不加 :start 和 :end ,则效果如下 :
② 两个对象显示不同时间段的数据
rrdtool graph1.png /
> --start now-2h / # 规定时间为2小时内
> DEF:value1=eth0.rrd:eth0_in:AVERAGE:end=now:start=end-1h / # 规定时间为1小时内
> DEF:value2=eth0.rrd:eth0_out:AVERAGE / # 没有指定 :start 和 :end,默认和 –-start 一样也是2小时
> AREA:value1#00ff00:in /
> LINE2:value2#ff0000:out:STACK
③ 把一段时间分为几段分别显示
rrdtool graph1.png /
> DEF:value1=eth0.rrd:eth0_in:AVERAGE:end=now:start=end-1h / # 当前1小时内
> DEF:value2=eth0.rrd:eth0_in:AVERAGE:end=now-1h:start=now-2h / # 2小时前
> DEF:value3=eth0.rrd:eth0_in:AVERAGE:end=now-2h:start=now-3h / # 3小时前
> LINE1:value1#00ff00:"1 hours ago" /
> LINE2:value2#ff0000:"2 hours ago" /
> LINE3:value3#000000:"3 hours ago"
说明文字(Label)
[-t|--title string] [-v|--vertical-label string]
-t 是用于图表上方的标题,-v 是用于 Y 轴的说明文字
图表大小(Size)
[-w|--width pixels] [-h|--height pixels]
这里说图表大小而不是图片大小,是因为 –w ,-h 控制的是 X/Y 轴共同围起来的那部分大小,而不是整个图片的大小
Y 轴上下限(Limits)
[-u|--upper-limit value] [-l|--lower-limit value] [-r|--rigid]
默认情况下,RRDtool 会自动调整 Y 轴的数字,来配合当前的数值大小。如果想禁止该特性,可以通过 –upper-limit 和-–lower-limit 来做限制,表示Y轴显示的值从多少到多少。如果没有指定 –rigid ,则在图表的上下边界处还是会有一些延伸,但如果指定了-–rigid ,则严格按照 –-upper-limit 和 –-lower-limit 绘制。
X/Y 轴刻度(Grid)
[-x|--x-grid GTM:GST:MTM:MST:LTM:LST:LPR:LFM]
[-x|--x-grid none]
[-y|--y-grid grid step:label factor]
[-y|--y-grid none]
[-Y|--alt-y-grid]
[-X|--units-exponent value]
有两种方法可以快速去掉 X/Y 轴的刻度,就是 –-x-grid none 和 –-y-grid none
① X 轴刻度的设置
GTM:GST :控制次要格网线的位置。GTM 是一个时间单位,可以是 SECOND、MINUTE、HOUR、DAY 、WEEK、MONTH、YEAR 。
GST 则是一个数字,控制每隔多长时间放置一根次要格线。例如我们要画一个1天的图表,决定每15分钟一根次要网格线,则格式为 MINUTE:15
MTM:MST : 控制主要网格线的位置。MTM 同样是时间单位,MST 是一个数字。接上面的例子,决定一个小时1根主要网格线。则格式为 HOUR:1
LTM:LST :控制每隔多长时间输出一个label 。决定为1小时1个 label 。则格式为 HOUR:1
LPR:LFM :LTM:LST 只是决定了 label 的显示位置了,没有指定要显示什么内容。LPR 指的是如何放置 label 。如果LPR 为0,则数字对齐格线(适用于显示时间)。如果不为0,则会做一些偏移(适用于显示星期几、月份等)。至于LFM 则需要熟悉一下 date 命令的参数,常用的有 %a(星期几)、%b(月份)、%d(天)、%H(小时)、%M(分)、%Y(年)。显示小时和分,用 %H%M
X 轴的刻度定义就是 –-x-grid MINUTE:15:HOUR:1:HOUR:1:0:’%H:%M’。最好把 %H:%M 括起来
② Y 轴刻度的设置
grid step :用于控制Y轴每隔多少显示一根水平线
label factor :默认为1,也就是在每根水平线的高度那里显示一个值。
例如下面就是一个例子 (每隔800显示一根水平线)
Y 轴还有一个很方便的选项就是 –Y ,它可以最大限度的优化 Y 轴的刻度,建议每次绘图都加上去。
Y 轴另外一个有用的选项就是 –X (虽然选项名是 -X ,但确实是用来设置 Y 轴刻度值的)。在上面的图我们看到 RRDtool 自动对 Y 轴的值进行调整,以 k 为单位显示。但如果你不想以 k 显示,而是想固定以某个单位来显示(M,b)该怎么办呢?这就要用到 –X 选项了。-X 后面跟一个参数,参数值范围是 -18、-15、-12、-9、-6 、-3、0、3、6、9、12、15、18 。0 表示以原值显示,3 表示数值除以1000,也就是以 k 为单位显示,6 就是以M 显示,9 就是以 G 显示。如果你给出1或者2,则 RRDtool 也可以接受,但会被“静悄悄”的改为0。下面就是一个以原值(-X 0)显示的例子
数字报表
GPRINT 就是在图表的下方(仍然属于图片的内部)输出最大值、最小值、平均值;
COMMENT 就是用来输出一些字符串,例如报表的表头。
A)GPRINT的格式是GPRINT:vname:CF:format 。由于 format 部分太多参数了,我这里就用最常用的那个 : %x.ylf 。
B)COMMENT 的格式是COMMENT:text 。要注意 COMMENT 默认是不输出换行的,如果要输出换行,必须用 “/n” 。
例:
rrdtool graph 1.png /
> --start now-1h -w 600 -n DEFAULT:8 /
> DEF:value1=eth0.rrd:eth0_in:AVERAGE /
> DEF:value2=eth0.rrd:eth0_out:AVERAGE /
> COMMENT:" /n" /
> COMMENT:" 当前值--------------平均值--------------最大值--------------最小值--------------/n" > COMMENT:" /n"
> AREA:value1#00FF00:"流入" /
> GPRINT:value1:LAST:'%13.2lf' /
> GPRINT:value1:AVERAGE:%13.2lf /
> GPRINT:value1:MAX:%13.2lf /
> GPRINT:value1:MIN:%13.2lf /
> COMMENT:" /n" /
> LINE2:value2#ff0000:"流出":STACK / # 注意这里是 STACK 方式
> GPRINT:value2:LAST:%13.2lf /
> GPRINT:value2:AVERAGE:%13.2lf /
> GPRINT:value2:MAX:%13.2lf /
> GPRINT:value2:MIN:%13.2lf /
> COMMENT:" /n" /
> COMMENT:” /n” /
> COMMENT:"LAST UPDATED /:$(date '+%Y-%m-%d %H/:%M')/n" –Y
从 RRD 文件中提取数据
语法格式
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 才可以查,否则会报错。
fetch 输出的第一列是 timestamp ,表示后面的数据是在什么时间收到的。”:” 后面就是DS的值。fetch 不能指定只取那个 DS 的数据,只能一次性取出全部 DS 的值。每个 DS 的值用空格进行分隔,一律采用科学记数法的格式。
例:
rrdtool fetch cpurand.rrd AVERAGE -r 120 -s 1180627320 -e 1180630800
DATA1 DATA2 DATA3
1180627440: 4.5000000000e+00 1.5403727077e+01 5.4163034477e+01
1180627560: 6.5000000000e+00 8.9438425101e+00 1.0622919044e+01
-------------
1180630680: 5.8500000000e+01 1.0622919044e+01 1.0622919044e+01
1180630800: 6.0500000000e+01 7.8323496210e+01 2.6644419677e+01
1180630920: 6.2500000000e+01 2.4839579434e+00 1.7082803611e+01
RRD 文件的dump&restore
dump
rrdtool dump sourcefile > objectfile
sourcefile RRD源文件(****.rrd)
objectfile 目标文件(****.xml)
例:
rrdtool dump cpu.rrd > cpu.xml
restore
rrdtool restore sourcefile objectfile
sourcefile 源文件(****.xml)
objectfile RRD目标文件(****.rrd)
例:
rrdtool restore cpu.xml cpu.rrd
获取 RRD 文件的信息
first
查看该 RRD 文件中某个 RRA 的第一个数据是在什么时候插入的(或者说第一次更新)。
例:
rrdtool first cpu.rrd
last
查看该 RRD 文件的最近一次更新。
例:
rrdtool last cpu.rrd
info
查看 rrd 文件的结构信息。
例:
rrdtool info cpu.rrd