大纲
一、MRTG的不足和RRDTool对比
二、RRDTool概述
三、安装RRDTool
四、RRDTool绘图步骤
五、rrdtool命令详解
六、RRDTool绘图案例
注,实验环境 CentOS 6.4 x86_64,软件版本 rrdtool-1.3.8(最新版的是1.4.8)。(说明:本博文的一些图片和内容自于开源社区与官方网站并不是所有内容全是原创)
一、MRTG的不足和RRDTool对比
1.MRTG软件的不足
MRTG监测网络流量很方便,但是如果需要监测其他的系统性能,比如CPU负载、系统负载、网络连接数等,就不是那么简单了。即使实现了这些功能,但管理起来非常麻烦。比如公司有一两千个被监测点,分布在不同的机房,为了管理方便需要将这些服务器和网络设备分类,这样的话就需要将这些被监测点放在不同的MRTG配置文件中,运行多个crontab,甚至还要自己写HTML页面对其进行管理。
MRTG毕竟是一套很老的软件,而且存在许多不足的地方,其作者Tobias Oetiker在1999年就已经开始开发另一套开源软件RRDTool来代替MRTG。现在RRDTool已经发展得很成熟,在功能MRTG难以与其相提并论。
2.RRDTool与MRTG对比
与MRTG一样,RRDTool也是由Tobias Oetiker撰写的开源软件,但RRDTool并非MRTG的升级版本,两者有非常大的区别,也可以说RRDTool是将用来取代MRTG的产品。下面是两个软件的一些优缺点的对比。
(1).MRTG
优点:
简单、易上手,基本安装完了之后只要修改一下配置文件即可使用。
缺点:
使用文本式的数据库,数据不能重复使用。
只能按日、周、月、年来查看数据。
由于MRTG本来只是用来监测网络的流量,所以只能存储两个DS(Data Source),即存储流量的输入和输出。
每取一次数据即需要绘图一次,浪费系统资源。
图像比较模糊。
无用户、图像管理功能。
没有详细日志系统。
无法详细了解各流量的构成。
只能用于TCP/IP网络,对于SAN网络流量无能为力。
不能在命令行下工作。
(2).RRDTool
优点:
使用RRD(Round Robin Database)存储格式,数据等于放在数据库中,可以方便地调用。比如,将一个RRD文件中的数据与另一个RRD文件中的数据相加。
可以定义任意时间段画图,可以用半年数据画一张图,也可以用半小时内的数据画一张图。
能画任意个DS,多种图形显示方式。
数据存储与绘图分开,减轻系统负载。
能任意处理RRD文件中的数据,比如,在浏览监测中我们需要将数据由Bytes转化为bits,可以将原始数据乘8。
缺点:
RRDTool的作用只是存储数据和画图,它没有MRTG中集成的数据采集功能。
在命令行下的使用非常复杂,参数极多。
无用户、图像管理功能。
RRDTool官方网站:
http://oss.oetiker.ch/rrdtool/
二、RRDTool概述
1.概述
RRDtool 代表 “Round Robin Database tool” ,作者同时也是 MRTG 软件的发明人。官方站点位于http://oss.oetiker.ch/rrdtool/ 。 所谓的“Round Robin” 其实是一种存储数据的方式,使用固定大小的空间来存储数据,并有一个指针指向最新的数据的位置。我们可以把用于存储数据的数据库的空间看成一个圆,上面有很多刻度。这些刻度所在的位置就代表用于存储数据的地方。所谓指针,可以认为是从圆心指向这些刻度的一条直线。指针会随着数据的读写自动移动。要注意的是,这个圆没有起点和终点,所以指针可以一直移动,而不用担心到达终点后就无法前进的问题。在一段时间后,当所有的空间都存满了数据,就又从头开始存放。这样整个存储空间的大小就是一个固定的数值。所以RRDtool 就是使用类似的方式来存放数据的工具, RRDtool 所使用的数据库文件的后缀名是'.rrd。如下图,
2.特点
首先 RRDtool 存储数据,扮演了一个后台工具的角色。但同时 RRDtool 又允许创建图表,这使得RRDtool看起来又像是前端工具。其他的数据库只能存储数据,不能创建图表。
RRDtool 的每个 rrd 文件的大小是固定的,而普通的数据库文件的大小是随着时间而增加的。
其他数据库只是被动的接受数据, RRDtool 可以对收到的数据进行计算,例如前后两个数据的变化程度(rate of change),并存储该结果。
RRDtool 要求定时获取数据,其他数据库则没有该要求。如果在一个时间间隔内(heartbeat)没有收到值,则会用 UNKN (unknow)代替,其他数据库则不会这样。
三、安装RRDTool
1.安装yum源
1
2
|
[root@node1 ~]
# rpm -ivh http://download.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm
[root@node1 ~]
# rpm -ivh http://pkgs.repoforge.org/rpmforge-release/rpmforge-release-0.5.3-1.el6.rf.x86_64.rpm
|
2.同步时间
1
|
[root@node1 ~]
# ntpdate 202.120.2.101
|
3.下载rrdtool的RPM包
1
|
[root@node1 ~]
# wget ftp://195.220.108.108/linux/centos/6.4/os/x86_64/Packages/rrdtool-1.3.8-6.el6.x86_64.rpm
|
4.yum安装rrdtool
1
|
[root@node1 ~]
# yum -y localinstall --nogpgcheck rrdtool-1.3.8-6.el6.x86_64.rpm
|
5.查看一下安装文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
[root@node1 ~]
# rpm -qa | grep rrdtool
rrdtool-1.3.8-6.el6.x86_64
[root@node1 ~]
# rpm -ql rrdtool
/usr/bin/rrdcgi
/usr/bin/rrdtool
#命令行工具
/usr/bin/rrdupdate
/usr/lib64/librrd
.so.4
#下面是库文件
/usr/lib64/librrd
.so.4.0.7
/usr/lib64/librrd_th
.so.4
/usr/lib64/librrd_th
.so.4.0.7
/usr/share/man/man1/bin_dec_hex
.1.gz
#下面是帮助文档
/usr/share/man/man1/cdeftutorial
.1.gz
/usr/share/man/man1/rpntutorial
.1.gz
/usr/share/man/man1/rrd-beginners
.1.gz
/usr/share/man/man1/rrdbuild
.1.gz
/usr/share/man/man1/rrdcgi
.1.gz
/usr/share/man/man1/rrdcreate
.1.gz
/usr/share/man/man1/rrddump
.1.gz
/usr/share/man/man1/rrdfetch
.1.gz
/usr/share/man/man1/rrdfirst
.1.gz
/usr/share/man/man1/rrdgraph
.1.gz
/usr/share/man/man1/rrdgraph_data
.1.gz
/usr/share/man/man1/rrdgraph_examples
.1.gz
/usr/share/man/man1/rrdgraph_graph
.1.gz
/usr/share/man/man1/rrdgraph_rpn
.1.gz
/usr/share/man/man1/rrdinfo
.1.gz
/usr/share/man/man1/rrdlast
.1.gz
/usr/share/man/man1/rrdlastupdate
.1.gz
/usr/share/man/man1/rrdresize
.1.gz
/usr/share/man/man1/rrdrestore
.1.gz
/usr/share/man/man1/rrdthreads
.1.gz
/usr/share/man/man1/rrdtool
.1.gz
/usr/share/man/man1/rrdtune
.1.gz
/usr/share/man/man1/rrdtutorial
.1.gz
/usr/share/man/man1/rrdupdate
.1.gz
/usr/share/man/man1/rrdxport
.1.gz
/usr/share/rrdtool
|
6.查看一下命令行工具
1
2
3
4
5
6
7
8
9
10
|
[root@node1 ~]
# rrdtool -h
RRDtool 1.3.8 Copyright 1997-2009 by Tobias Oetiker <[email protected]>
Compiled Aug 21 2010 10:57:18
Usage: rrdtool [options]
command
command_options
Valid commands: create, update, updatev, graph, graphv, dump, restore,
last, lastupdate, first, info, fetch, tune,
resize, xport
RRDtool is distributed under the Terms of the GNU General
Public License Version 2. (www.gnu.org
/copyleft/gpl
.html)
For
more
information
read
the RRD manpages
|
注,使用 man rrdtool 可以查看详细的使用方法。好了,到这里我们就安装完成了,下面我们来说一下RRDTool的绘图步骤。
四、RRDTool绘图步骤
步骤一︰建立RRD文件,这个文件说来就是RRDtool的专属数据库。RRDtool以自有的格式存放数据。下面会讲解!
步骤二︰抓取数据个人觉得是整个RRDtool最困难的一部分,因为RRDtool的数据是要靠自己在创建RRD数据库时定义出来,不像MRTG内建抓数据功能,但是却因为如此,可以给RRDtool画图的数据弹性也比较大,例如︰snmp查询结果、系统状态、网页中特定数据统计等等。
步骤三︰将抓下来的数据就用rrdtool update的指令进行更新到的RRD数据库中,让图表能画出最新的流量。
步骤四︰这就是重点啦!通过rrdtool graph的指令来依据RRD数据库的数据进行绘图,这也是使用者唯一看的到的东西,若规划的不好会影响使用者阅读上的困难!
循环︰由于要完成动态绘图的图表,第二步骤到第四步骤必须不断的重复执行以维持资料的更新,目前知道要达成循环的方法有两种︰
在Script中使用循环
使用crontab任务计划
五、rrdtool命令详解
1.创建RRD数据库
create 语法
1
2
3
4
5
|
rrdtool create filename
[--start|-b start
time
]
[--step|-s step]
DS:ds-name:DST:dst arguments
#最后获取的数据是PDP,更新数据时要考滤DS顺序(*把所有要更新的数据,按照DS定义的顺序用冒号格开*)
RRA:CF:cf arguments
#最后获取的数据是CDP,绘图时使用的是这些数据
|
参数详解:
DS:DS 用于定义 Data Soure 。也就是用于存放结果的变量名。DS是用来申明数据源的,也可以理解为申明数据变量,也就是你要检测的端口对应的变量名,这个参数在画图的时候还要使用的。
DST:DST 就是DS的类型。有 COUNTER、GUAGE、DERIVE、ABSOLUTE、COMPUTE 5种。由于网卡流量属于计数器型,所以这里应该为 COUNTER 。
RRA:RRA 用于指定数据如何存放。我们可以把一个RRA 看成一个表,各保存不同 interval 的统计结果。RRA的作用就是定义更新的数据是如何记录的。比如我们每5分钟产生一条刷新的数据,那么一个小时就是12条。每天就是288条。这么庞大的数据量,一定不可能都存下来。肯定有一个合并(consolidate)数据的方式,那么这个就是RRA的作用了。
PDP:Primary Data Point 。正常情况下每个 interval RRDtool 都会收到一个值;RRDtool 在收到脚本给来的值后会计算出另外一个值(例如平均值),这个 值就是 PDP ;这个值代表的一般是“xxx/秒”的含义。注意,该值不一定等于RRDtool 收到的那个值。除非是GAUGE ,可以看下面的例子就知道了
CF:CF 就是 Consolidation Function 的缩写。也就是合并(统计)功能。有 AVERAGE、MAX、MIN、LAST 四种分别表示对多个PDP 进行取平均、取最大值、取最小值、取当前值四种类型。具体作用等到 update 操作时再说。
CDP:Consolidation Data Point 。RRDtool 使用多个 PDP 合并为(计算出)一个 CDP。也就是执行上面 的CF 操作后的结果。这个值就是存入 RRA的数据,绘图时使用的也是这些数据
下面是RRA与PDP、CDP之间的关系图,
(0).filename
默认是以 .rrd 结尾,但也以随你设定。
(1).--start|-b start time
设定RRD数据库加入的第一个数据值的时间,从1970-01-01 00:00:00 UTC时间以来的时间(秒)。RRDtool不会接受早于或在指定时刻上的任何数值。默认值是now-10s;如果 update 操作中给出的时间在 –-start 之前,则 RRDtool拒绝接受。--satrt 选项也是可选的。 如果你想指定--start 为1天前,可以用CODE:--start $(date -d '1 days ago' +%s)。注意,--start 选项的值必是 timestamp 的格式。
(2).--step|-s step
指定数据将要被填入RRD数据库的基本的时间间隔。默认值是300秒;
(3).DS:ds-name:DST:dst arguments DS(Data Source)
DS:DS 用于定义 Data Soure 。也就是用于存放结果的变量名。 DS是用来申明数据源的,也可以理解为申明数据变量,也就是你要检测的端口对应的变量名,这个参数在画图的时候还要使用的。这里开始定义RRD数据的基本属性;单个RRD数据库可以接受来自几个数据源的输入。在DS选项中要为每个需要在RRD中存储的数据源指定一些基本的属性;ds-name数据域命名;DST定义数据源的类型,dst arguments参数依赖于数据源的类型。
案例:DS:mysql:COUNTER:600:0:100000000
DS(Data Source,数据源)表达式总共有六个栏位:
DS 表示这个为DS表达式
ds-name 数据域命名
DST 定义数据源的类型
heartbeat 有效期(heartbeat),案例里的值为'600',假设要取12:00的数据,而前后300秒里的值(11:55-12:05)经过平均或是取最大或最小都算是12:00的有效值;
min 允许存放的最小值,此例允许最小为0。
max 允许存放的最大值,最大为100000000。
注,如果不想设限制可以再第五个栏位和第六个栏位以 "U:U"表示(U即Unknown)。
DST定义数据源的类型。数据源项的后续参数依赖于数据源的类型。对于GAUGE、COUNTER、DERIVE、以及ABSOLUTE,其数据源的格式为: DS:ds-name:GAUGE | COUNTER | DERIVE | ABSOLUTE:heartbeat:min:max。DST 的选择是十分重要的,如果选错了 DST ,即使你的脚本取的数据是对的,放入 RRDtool 后也是错误的,更不用提画出来的图是否有意义了。
GAUGE :GAGUE 和上面三种不同,它没有“平均”的概念,RRDtool 收到值之后字节存入 RRA 中。
COUNTER :必须是递增的,除非是计数器溢出。在这种情况下,RRDtool 会自动修改收到的值。例如网络接口流量、收到的packets 数量都属于这一类型。
DERIVE:和 COUNTER 类似。但可以是递增,也可以递减,或者一会增加一会儿减少。
ABSOLUTE :ABSOLUTE 比较特殊,它每次都假定前一个interval的值是0,再计算平均值。
COMPUTE :COMPUTE 比较特殊,它并不接受输入,它的定义是一个表达式,能够引用其他DS并自动计算出某个值。例如CODE:DS:eth0_bytes:COUNTER:600:0:U DS:eth0_bits:COMPUTE:eth0_bytes,8,* 则 eth0_bytes 每得到一个值,eth0_bits 会自动计算出它的值:将 eth0_bytes 的值乘以 8 。不过 COMPUTE 型的 DS 有个限制,只能应用它所在的 RRD 的 DS ,不能引用其他 RRD 的 DS。 COMPUTE 型 DS 是新版本的 RRDtool 才有的,你也可以用 CDEF 来实现该功能。如:CDEF:eth0_bits=eth0_bytes,8,*
DST 实例说明,
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。
下面我们来建立一个RRD库文件,
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
[root@node1 ~]
# rrdtool create eth0.rrd \
> --step 300 \
> DS:eth0_in:COUNTER:600:0:12500000 \
# 600 是 heartbeat;0 是最小值;12500000 表示最大值;
> DS:eth0_out:COUNTER: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@node1 ~]
# ll -h eth0.rrd
-rw-r--r-- 1 root root 41K 10月 11 10:16 eth0.rrd
|
有的人可能会问,上面有两个 DS,那 RRA 中究竟存的是那个 DS 的数据呢?实际上,这些 RRA 是共用的,你只需建立一个 RRA,它就可以用于全部的 DS 。所以在定义 RRA 时不需要指定是给那个 DS 用的。
(4).RRA:CF:cf arguments
RRA的作用就是定义更新的数据是如何记录的。比如我们每5分钟产生一条刷新的数据,那么一个小时就是12条。每天就是288条。这么庞大的数据量,一定不可能都存下来。肯定有一个合并(consolidate)数据的方式,那么这个就是RRA的作用了。如下图,
RRD的一个目的是在一个环型数据归档中存储数据。一个归档有大量的数据值或者每个已定义的数据源的统计,而且它是在一个RRA行中被定义的。当一个数据进入RRD数据库时,首先填入到用 -s 选项所定义的步长的时隙中的数据,就成为一个pdp值,称为首要数据点(Primary Data Point)。该数据也会被用该归档的CF归并函数进行处理。可以把各个PDPs通过某个聚合函数进行归并的归并函数有这样几种:AVERAGE、MIN、MAX、LAST等。这些归并函数的RRA命令行格式为:RRA:AVERAGE | MIN | MAX | LAST:xff:steps:rows。
什么是 CF?
以上面的案例中第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。
解释度(Resolution)
这里要提到一个 Resolution 的概念,在官方文档中多处提到 resolution 一词。Resolution 究竟是什么?Resolutino 有什么用?举个例子,如果我们要绘制1小时的数据,也就是60分钟,那么我们可以从第一个RRA 中取出12个 CDP 来绘图;也可以从第2个 RRA中取出3个 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 中提到它。
xff 字段
细心的朋友可能会发现,在 RRA 的定义中有一个数值,固定是 0.5 ,这个到底是什么东东呢?
这个称为 xff 字段,是 xfile factor 的缩写。让我们来看它的定义 :
QUOTE:
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)
这个看起来有点头晕,我们举个简单的例子 :例如
CODE: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 了。
2.抓取数据
简单说,就是用shell写个脚本去不断的收集数据。对于不懂shell编辑的博友可以去网上找点资料学习一下,很简单的。下面是利用snmp来获取进入网卡的流量。
1
2
|
[root@node1 ~]
# snmpget -v 2c -c public 192.168.18.201 ifInOctets.2
IF-MIB::ifInOctets.2 = Counter32: 57266195
|
上面的例子是使用snmpget来抓取192.168.18.201的网卡输入流量,-v 2c表示snmp版本号,-c public snmp共同体名称,192.168.18.201是这台主机的IP地址,ifInOctets.2是指eth0网卡的输入流量,ifInOctets.1是指lo0网卡的输入流量。从上面我们可以看出,eth0输入的流量为57266195。下面我们来截取一下输入流量,
1
2
|
[root@node1 ~]
# snmpget -v 2c -c public 192.168.18.201 ifInOctets.2 | sed -e 's/.*ter32: \(.*\)/\1/'
57463513
|
我们得到的值为57463513,这就是我们要的结果。我们只要用shell脚本写个循环就可以收集网卡的输入流量了,再用rrdtool update命令将收集到的数据更新到RRD数据库中即可。
当然,您不一定要使用snmpget,也可以使用snmpwalk、tcpdump等等抓取数据回来分析,说夸张点,凡是有变化的数据都可以经过处理变成我们要的资料,然后画成图表。
3.更新RRD数据库数据
update 语法
1
2
3
4
|
rrdtool update filename [--template|-t ds-name[:dsname]...] N|timestamp:value[:value...]
filename RRD数据库文件名称
--template|-t ds-name[:ds-name] 要更新RRD数据库中数据源的名称,其中-t指定数据源的顺序
N|timestamp:value[:value...] 时间:要更新的值
|
案例:
1
2
|
[root@node1 ~]
#rrdtool update eth0.rrd 1381467942:60723022 或
[root@node1 ~]
# rrdtool update eth0.rrd N:60723022
|
其中,1381467942是当前的时间戳,可以用date +%s命令获得,或者直接用N代替。60723022是当前要更新的流量数据,可以用shell脚本获得。下面我们来查看一下,更新的数据。
1
|
[root@node1 ~]
# rrdtool fetch eth0.rrd AVERAGE
|
4.绘制图表
使用RRDtool 我们最关心什么?当然是把数据画出来了。虽然前面谈了很多,但这些都是基础来的。掌握好了,可以让你在绘图时更加得心应手。
graph 语法
1
2
3
4
5
6
7
8
9
10
|
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四种。
(1).DEF 是 Definition (定义)的意思。定义什么呢?你要绘图,总要有数据源吧?DEF 就是告诉 RRDtool 从那个 RRD 中取出指定。
为什么还有一个 CF 字段?因为 RRA 有多种CF 类型,有些 RRA 可能用来保存平均值、有些 RRA 可能用于统计最大值、最小值等等。所以你必须同时指定使用什么 CF 类型的 RRA的数据。
至于 :start 和 :end 、:reduce 则用得比较少,最常用的就是 :step 了,它可以让你控制 RRDtool 从那个 RRA 中取数据。
(2).VDEF 是 Variable Definition (变量定义)的意思。定义什么呢?记得 MRTG 在图表的下面有一个称之为 Legend 的部分吗?那里显示了1个或者2个 DS (MRTG 没有 DS 一说,这里是借用 RRDtool 的)的 “最大值”、“平均值”、“当前值”。
RRDtool 中用 VDEF 来定义。这个变量专门存放某个 DS 某种类型的值,例如 eth0_in 的最大值、eht0_out 的当前值等。当你需要象MRTG 一样输出数字报表(Legend) 时,就可以在 GPRINT 子句(sub clause)中调用它。同样它也需要用一个变量来存放数值。要注意的是,旧版 的 RRDtool 中是用另外一种格式来达到相同的目的。新版的 RRDtool 则推荐使用VDEF语句。但在使用过程中,却发现 VDEF 的使用反而造成了困扰。 例如你有5个 DS 要画,每个 DS 你都想输出最大值、最小值、平均值 、当前值。 如果使用 VDEF ,则需要 4 * 5 = 20 个 VDEF 语句,这会造成极大的困扰。具体例子可以看第十一节“数字报表”部分。
(3).CDEF 是 Calculation Define 的意思。使用过MRTG 的都会体会到一点,MRTG 的计算能力实在太差了。例如你有两个 Target ,一个是 eth0_in , 一个是 eth0_out,如果要把它们相加起来,再除以8,得出 bytes 为单位的值,如何计算呢?或者说你只想看 eth0_in 中超过 10Mb/s 的那部分, 其余的不关心,又如何实现呢?因为 MRTG 不能对它从 log 取出来的数据进行修改,只能原原本本的表现,所以很难满足我们的要求。而使用 CDEF , 这一切都可以很容易的实现。CDEF 支持很多数学运算,甚至还支持简单的逻辑运算 if-then-else ,可以解决前面提到的第2个问题:如何只绘制你所关 心的数据。不过这一切都需要熟悉 RPN 的语法.所以我们放到下一节介绍,这一节就介绍把 RRDtool 中的数据以图表的方式显示出来。
(4).其它选项分类
本部分我们按照官方文档的方式,把选项分成几大类,分为 :
Time range : 用于控制图表的X轴显示的起始/结束时间,也包括从RRA中提取指定时间的数据。
Labels :用于控制 X/Y 轴的说明文字。
Size :用于控制图片的大小。
Limits :用于控制 Y 轴的上下限。
Grid :用于控制 X/Y 轴的刻度如何显示。
Miscellaneous :其他选项。例如显示中文、水印效果等等。
Report :数字报表
注,需要说明的是,本博文中并不是列出了所有选项的用法,只是列出较为常用的选项,如果想查看所有选项的的用法,可以到官方站点下载文档。其实大部分选项我们都可以使用默认值不需要修改的。下面是常用选项,
1
|
rrdtool graph filename [option ...] [data definition ...] [data calculation ...] [variable definition ...] [graph element ...] [print element ...]
|
filename 要绘制的图片名称
Time range时间范围
[-s|--start time] 启始时间[-e|--end time]结束时间 [-S|--step seconds]步长
Labels
[-t|--title string]图片的标题 [-v|--vertical-label string] Y轴说明
Size
[-w|--width pixels] 显示区的宽度[-h|--height pixels]显示区的高度 [-j|--only-graph]
Limits
[-u|--upper-limit value] Y轴正值高度[-l|--lower-limit value]Y轴负值高度 [-r|--rigid]
Data and variables
DEF:vname=rrdfile:ds-name:CF[:step=step][:start=time][:end=time]
CDEF:vname=RPN expression
VDEF:vname=RPN expression
好了,到这里我们RRDTool命令工具的基本使用,就讲解到这里了更多详细的内容请参考官方网站。好了,下面我们来演示一个完整的案例。
六、RRDTool绘图案例
案例:利用RRDTool来绘制mysql服务器查询次数的曲线图。
1.安装mysql服务器
1
|
[root@node1 ~]
# yum install -y mysql-server
|
2.启动并测试
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
|
[root@node1 ~]
# chkconfig mysqld on
[root@node1 ~]
# service mysqld start
初始化 MySQL 数据库: Installing MySQL system tables...
OK
Filling help tables...
OK
To start mysqld at boot
time
you have to copy
support-files
/mysql
.server to the right place
for
your system
PLEASE REMEMBER TO SET A PASSWORD FOR THE MySQL root USER !
To
do
so, start the server,
then
issue the following commands:
/usr/bin/mysqladmin
-u root password
'new-password'
/usr/bin/mysqladmin
-u root -h node1.
test
.com password
'new-password'
Alternatively you can run:
/usr/bin/mysql_secure_installation
which
will also give you the option of removing the
test
databases and anonymous user created by default. This is
strongly recommended
for
production servers.
See the manual
for
more
instructions.
You can start the MySQL daemon with:
cd
/usr
;
/usr/bin/mysqld_safe
&
You can
test
the MySQL daemon with mysql-
test
-run.pl
cd
/usr/mysql-test
; perl mysql-
test
-run.pl
Please report any problems with the
/usr/bin/mysqlbug
script!
[确定]
正在启动 mysqld: [确定]
[root@node1 ~]
# mysql
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection
id
is 2
Server version: 5.1.69 Source distribution
Copyright (c) 2000, 2013, Oracle and
/or
its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and
/or
its
affiliates. Other names may be trademarks of their respective
owners.
Type
'help;'
or
'\h'
for
help. Type
'\c'
to
clear
the current input statement.
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
|
test
|
+--------------------+
3 rows
in
set
(0.00 sec)
mysql>
|
3.创建RRD数据库文件
1
2
3
4
5
6
7
8
|
[root@node1 ~]
# rrdtool create mysql.rrd --step 3 DS:mysqlselect:COUNTER:5:0:U RRA:AVERAGE:0.5:1:28800 RRA:AVERAGE:0.5:10:2880 RRA:MAX:0.5:10:2880 RRA:LAST:0.5:10:2880
[root@node1 ~]
# ll -h
总用量 620K
-rw-------. 1 root root 970 8月 17 18:50 anaconda-ks.cfg
-rw-r--r--. 1 root root 16K 8月 17 18:50
install
.log
-rw-r--r--. 1 root root 4.1K 8月 17 18:48
install
.log.syslog
-rw-r--r-- 1 root root 294K 10月 11 15:57 mysql.rrd
-rw-r--r-- 1 root root 294K 10月 10 21:53 rrdtool-1.3.8-6.el6.x86_64.rpm
|
4.抓取数据
1
2
|
[root@node1 ~]
# mysql --batch -e "show global status like 'com_select'" | awk '/Com_select/{print $2}'
5
|
5.更新RRD数据库
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
[root@node1 ~]
# vim getselect.sh
#!/bin/bash
#
while
true
;
do
SELECT=`mysql --batch -e
"show global status like 'com_select'"
|
awk
'/Com_select/{print $2}'
`
rrdtool update mysql.rrd N:$SELECT
sleep
3
done
[root@node1 ~]
# bash -n getselect.sh
[root@node1 ~]
# bash -x getselect.sh
+
true
++ mysql --batch -e
'show global status like '
\
''
com_select
'\''
'
++
awk
'/Com_select/{print $2}'
+ SELECT=10
+ rrdtool update mysql.rrd N:10
+
sleep
3
+
true
++
awk
'/Com_select/{print $2}'
++ mysql --batch -e
'show global status like '
\
''
com_select
'\''
'
+ SELECT=11
+ rrdtool update mysql.rrd N:11
+
sleep
3
+
true
++ mysql --batch -e
'show global status like '
\
''
com_select
'\''
'
++
awk
'/Com_select/{print $2}'
+ SELECT=12
+ rrdtool update mysql.rrd N:12
|
注,让这个脚本一直执行着。
6.创建一个测试数据库
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
[root@node1 ~]
# mysql
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection
id
is 55
Server version: 5.1.69 Source distribution
Copyright (c) 2000, 2013, Oracle and
/or
its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and
/or
its
affiliates. Other names may be trademarks of their respective
owners.
Type
'help;'
or
'\h'
for
help. Type
'\c'
to
clear
the current input statement.
mysql> create database testdb;
Query OK, 1 row affected (0.01 sec)
mysql> use testdb;
Database changed
mysql> create table tb1 (
id
int UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, name char(50) NOT NULL);
Query OK, 0 rows affected (0.02 sec)
mysql> show tables;
+------------------+
| Tables_in_testdb |
+------------------+
| tb1 |
+------------------+
1 row
in
set
(0.00 sec)
mysql>
|
7.创建一个脚本不断的插入数据并查询
1
2
3
4
5
6
7
8
9
10
|
[root@node1 ~]
# vim insert.sh
#!/bin/bash
#
for
I
in
{1..200000};
do
mysql -e
"INSERT INTO testdb.tb1(name) VALUES ('stu$I')"
mysql -e
"SELECT * FROM testdb.tb1"
&>
/dev/null
done
~
[root@node1 ~]
# bash -n insert.sh
[root@node1 ~]
# bash -x insert.sh
|
8.查看一下RRD数据库更新的数据
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
|
[root@node1 ~]
# rrdtool fetch -r 3 mysql.rrd AVERAGE
1381478757: -nan
1381478760: -nan
1381478763: -nan
1381478766: -nan
1381478769: -nan
1381478772: -nan
1381478775: 2.7153386392e-01
1381478778: 3.2831536999e-01
1381478781: 3.2891623754e-01
1381478784: 3.2705226490e-01
1381478787: 3.2799497906e-01
1381478790: 3.2750147283e-01
1381478793: 3.2962107218e-01
1381478796: 3.3022497969e-01
1381478799: 3.3027211905e-01
1381478802: 3.3020369194e-01
1381478805: 3.2946024073e-01
1381478808: 3.2988230260e-01
1381478811: 3.2969005472e-01
1381478814: 3.2974230463e-01
1381478817: 3.3001057711e-01
1381478820: 3.3019278582e-01
1381478823: 3.3083777490e-01
1381478826: 3.3015850009e-01
1381478829: 3.2968813815e-01
1381478832: 3.3021007195e-01
1381478835: 3.2890877932e-01
1381478838: 3.2919982365e-01
1381478841: 3.2820752812e-01
1381478844: 3.2498916047e-01
1381478847: 3.2435105446e-01
1381478850: 3.2631508451e-01
1381478853: 3.2927988387e-01
1381478856: 3.3061808059e-01
1381478859: 3.3065099981e-01
1381478862: 3.3079060547e-01
1381478865: 3.2993297013e-01
1381478868: 3.2998088978e-01
1381478871: 3.3045720109e-01
1381478874: 3.3052361682e-01
1381478877: 3.3021445518e-01
1381478880: 3.3033678729e-01
1381478883: 3.3017146110e-01
1381478886: 3.2932443118e-01
1381478889: 3.2872916025e-01
1381478892: 3.2942230122e-01
1381478895: 3.3004157568e-01
1381478898: 3.3035752652e-01
1381478901: 3.3026495130e-01
1381478904: 4.2927608935e-01
1381478907: 5.6199888336e-01
1381478910: 3.2960053815e-01
1381478913: 3.3019513627e-01
1381478916: 3.3008973582e-01
1381478919: 3.3023471404e-01
1381478922: 3.3044897038e-01
1381478925: 3.3025127245e-01
1381478928: 3.2999671137e-01
1381478931: 3.2995130475e-01
1381478934: 3.3001845566e-01
1381478937: 3.3004261932e-01
1381478940: 3.2985954162e-01
1381478943: 3.2962262303e-01
1381478946: 3.3033462847e-01
1381478949: 3.3000997317e-01
1381478952: 3.3023836505e-01
1381478955: 3.2987551061e-01
1381478958: 3.3038940726e-01
1381478961: 3.3047901095e-01
1381478964: 3.2999606597e-01
1381478967: 3.3021352982e-01
1381478970: 3.2998445954e-01
1381478973: 3.3029458891e-01
1381478976: 3.3009257605e-01
1381478979: 3.3008453893e-01
1381478982: 3.2998650516e-01
1381478985: 3.3014434356e-01
1381478988: 3.2950044395e-01
|
注,大家可以看到现在已经有很多的数据了,下面我们来简单的制作一查询曲线图。
9.制作查询曲线图
1
2
|
[root@node1 ~]
# rrdtool graph mysql.png -s 1381478754 -t "mysql select" -v "selects/3" DEF:select3=mysql.rrd:mysqlselect:AVERAGE:step=3 LINE1:select3#FF0000:"select"
497x174
|
10.取出mysql.png图片并查看
好了,到这里我们RRDTool的讲解就全部结束了,想了解更多的RRDTool相关的知识一方面大家可以参考官方文档,另一方面大家可以参考一下这篇博客http://bbs.chinaunix.net/forum.php?mod=viewthread&tid=864861&page=1,我认为还是写的比较详细的,好了这一篇博客就到这边了,希望大家有所收获吧^_^……