Chinaunix首页 | 论坛 | 博客
  • 博客访问: 779953
  • 博文数量: 95
  • 博客积分: 6011
  • 博客等级: 准将
  • 技术积分: 1342
  • 用 户 组: 普通用户
  • 注册时间: 2008-04-12 16:58
文章分类

全部博文(95)

文章存档

2009年(44)

2008年(51)

我的朋友

分类: 服务器与存储

2009-05-08 14:46:01

 RRD 文件中提取数据

**********************************************************************************************************************
注 :该教程参考了如下内容 :
A
)官方文档 :
B
abel 兄的大作 :

作者 :ailms
版本 :v1
最后修改 :2006/11/17 17:35
**********************************************************************************************************************

一)前言
RRD 
 Round Robin Database 的意思,那么是否可以象普通的数据库进行查询操作呢?

答案是可以的。fetch 就是用来做这种事情的工具。当然 fetch 不能和 select 语句相比,它只是根据用户指定的时间,

从合适的 RRA 中取出数据,并加以格式化。不过和 MRTG 相比,已经好很多了,至少你不用取看该死的 log 文件。

实际上,fetch 操作其实可以不学,因为 RRDtool 会自动帮你选好数据。但你如何确定 RRDtool 取的数据就是你想要的呢?

或者说你如何证明 RRDtool 绘制出来的图是正确的呢?

废话少说,下面开始正文

二)fetch 操作的语法

CODE:

rrdtool fetch filename CF [--resolution|-r resolution] [--start|-s start] [--end|-e end]


其中 --start--end-r 都是可选的 。RRDtool 默认的 --end  now --start  end-1day ,也就是1天前。

CF 
可以是 AVERAGEMAXMINLAST ,当然必须建库时有该 CF 类型的 RRA 才可以查,否则会报错。


三)fetch 如何取数据

在确定了时间范围后,RRDtool 会从多个 RRA 中挑选最佳的那个 RRA 的数据。至于什么是最佳,则从两个方面考虑 :

A
第一是该 RRA 的数据要尽可能的覆盖所请求的时间范围。如何计算一个 RRA 的覆盖时间呢?以 eth0.rrd 的第一个RRA 为例,

    
 600 个记录,每个记录相隔300秒,则总的时间覆盖范围是180000 ≈2天,所以如果 –-start  -–end 规定的时间范围
   
    
大于2天,则 RRDtool 不会从该 RRA 中取数据。

B
第二是 resolution 的要求。还是上面的例子,如果是要画3天的数据,从时间覆盖范围上来讲,第23 RRA 都符合要求。

    
那究竟挑选那个 RRA 的数据呢?如果 fetch 中有指定 –r 选项,则挑选 resolution 等于 –r 指定的值那个 RRA 的数据。如果没有 
   
    –r 
选项,则从第一个合适的 RRA 中取数据。

C
fetch 如果不加 –-start--end-r ,则默认输出 resolution 最小的那个 RRA 的数据。就像下面的例子1一样。

四)实际例子

实例一 :默认情况

CODE:

[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



CODE:

[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 指定时间范围

CODE:

[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风格的时间

CODE:

[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 风格的时间比较方便。

可以省去计算的麻烦,别人也比较容易看。

实例四 :提取指定 resolution 的数据

CODE:

[root@dns1 bob]# rrdtool fetch eth0.rrd AVERAGE --start 1164467700 --end start+1day -r 1200 |more
                     eth0_in          eth0_out

1164468000: 1.7899370295e+01 3.8782610300e+00
1164469200: 2.0828335735e+01 3.4166666667e-01
1164470400: 1.4581351504e+01 3.5000000000e-02
。。。。。。(中间省略很多)
1164554400: 9.4367707174e+01 9.4866775629e+01
[root@dns1 bob]


可以看到,现在记录两两之间的时间间隔变成了1200 了。输出的行数为 (86400/1200+1=73 72+1)。


实例五:如果指定一个不存在的 resolution 呢?

CODE:

[root@dns1 bob]# rrdtool fetch eth0.rrd AVERAGE --start 1164467700 --end start+1day -r 1000 |more 
                     eth0_in          eth0_out

1164468000: 1.7899370295e+01 3.8782610300e+00
1164469200: 2.0828335735e+01 3.4166666667e-01
。。。。。。(中间省略很多)
1164554400: 9.4367707174e+01 9.4866775629e+01
[root@dns1 bob]#


我们指定的 resolution  1000 ,但并没有那个 RRA  resolution  1000,所以 RRDtool 挑选了第一个合适的 resolution 

也就是 1200 的那个 RRA 的数据作为结果输出。注意,RRDtool 只会挑选 resolution  –r 指定的值相等或者更高的 RRA ,不会挑

选比 –r 指定的值小的 RRA 
例如在该例子中,RRDtool 就不会挑选 resolution=300 的第一个 RRA 。为什么呢?

各位可以自己根据第三部分“fetch 如何提取数据的两个准则考虑一下


实例六 :再来看一个 –r 的例子

如果我不想指定 –-start 或者 –end ,就想看 resolution  1200 呢?

CODE:

[root@dns1 bob]# rrdtool fetch eth0.rrd AVERAGE -r 1200
                     eth0_in          eth0_out

1164470400: 1.4581351504e+01 3.5000000000e-02
1164471600: 1.9312781373e+01 3.5000000000e-02
。。。。。(中间省略很多)
1164555600: 8.5249300043e+01 7.0171152327e+01
1164556800: nan nan
[root@dns1 bob]#


咦?为什么还是使用记录的时间间隔还是 300 秒呢?我们不是指定了 –r 1200 吗?

老实说,这种方法 90% 以上的机率是不会成功吗?那应该怎么办呢?

实例七 :正确使用 –r 的方式

CODE:

[root@dns1 bob]# rrdtool fetch eth0.rrd AVERAGE -r 1200 --end $((($(date +%s)/1200)*1200)) |more
                     eth0_in          eth0_out

1164470400: 1.4581351504e+01 3.5000000000e-02
1164471600: 1.9312781373e+01 3.5000000000e-02
1164472800: 1.7383358822e+01 3.5000000000e-02
1164474000: 1.4781054841e+01 3.3225406191e-01
。。。。。。(中间省略很多)
1164555600: 8.5249300043e+01 7.0171152327e+01
1164556800: nan nan
[root@dns1 bob]#


现在 resolution 已经变成 1200 的了。同理,如果想看 720086400 resolution RRA,只要把 end 部分的 ( )中的数字替换为相应的值就可以了。

CODE:

[root@dns1 bob]# rrdtool fetch eth0.rrd AVERAGE -r 7200 --end $((($(date +%s)/7200)*7200)) 

[root@dns1 bob]# rrdtool fetch eth0.rrd AVERAGE -r 86400 --end $((($(date +%s)/86400)*86400))


实例八 :关于 fetch 提取数据准则1的测试

CODE:

[root@dns1 bob]# rrdtool fetch eth0.rrd --start now-3day AVERAGE |more
                     eth0_in          eth0_out

1164298800: nan nan
1164300000: nan nan
。。。。。。(中间省略很多)
1164556800: 6.4118014239e+01 1.8871145267e+01
1164558000: nan nan
[root@dns1 bob]#


和第一个例子不同,这次的 resolution  1200 了?为什么呢?因为我们指定的时间范围是3天,而第一个 RRA只保存2天的数据多一点,所以 RRDtool 不会从

 RRA 取数据,那么会从那个 RRA 取数据呢?由于我们没有指定 –r 选项,所以 RRDtool 选择1200 的那个 RRA 

实例九 :关于 fetch 提取数据准则2的测试

CODE:

[root@dns1 bob]# rrdtool fetch eth0.rrd --start now-3day AVERAGE -r 7200 |more
                     eth0_in          eth0_out

1164304800: nan nan
1164312000: nan nan
1164319200: nan nan
。。。。。。(中间省略很多)
1164549600: 5.1899602485e+01 4.3073128067e-01
1164556800: 7.9766222122e+01 4.0644151093e+01
1164564000: nan nan
[root@dns1 bob]#


现在 resolution 不再是 1200 ,而是指定的 7200 了。

因为虽然 resolution=1200  RRA 就可以满足 --start  --end 的需求,

但因为 -r 指定 resolution=7200 ,所以从第3 RRA 中取数据

五)总结

从上面我们可以看出,fetch 实际上是非常复杂的一个命令,如果想要输出你所要的数据,就必须考虑好几个因素 :

A
第一是具体想输出的时间范围?

B
第二是计算好 –-start  –end。建议至少给出一个,最好2个都给出

C
第三是如果有多个RRA符合条件,则使用 –r 指定具体的 resolution

使用RRDtool 进行绘图(一)

**********************************************************************************************************************
注 :该教程参考了如下内容 :
A
)官方文档 :
B
abel 兄的大作 :

作者 :ailms
版本 :v1
最后修改 :2006/11/17 17:35
**********************************************************************************************************************

一)前言

使用RRDtool 我们最关心什么?当然是如何把数据画出来了。虽然前面谈了很多,但这些都是基础来的。掌握好了,可以让你在绘图时更加得心应手。

本来还有 RPN (反向波兰表达式)一节的,但考虑一下,觉得还是放到后面,先从基本的绘图讲起。

这一节的内容虽然很多,但基本都是实验性的内容,只要多试几次就可以了。

二、graph 操作的语法

CODE:

rrdtool graph filename [option ...] 
[data definition ...]
[data calculation ...] 
[variable definition ...]
[graph element ...]
[print element ...]


其中的 data definitonvariable definition data calculation、分别是下面的格式

CODE:

DEF:=::[:step=][:start=


其中 filename 就是你想要生成的图片文件的名称,默认是 png 。你可以通过选项修改图片的类型,可以有 PNGSVGEPSPDF四种。

A
DEF  Definition (定义)的意思。定义什么呢?你要绘图,总要有数据源吧?DEF 就是告诉 RRDtool 从那个 RRD 中取出指定

DS
eth0_ineth0_out)的某个类型的统计值(还可以指定 resolutionstartend),并把这一切放入到一个变量 中 。

你可能会感到奇怪,为什么还有一个 CF 字段?因为 RRA 有多种   CF 类型,有些 RRA 可能用来保存平均值、有些 RRA 可能用于统计最大值、

最小值等等。所以你必须同时指定使用什么 CF 类型的 RRA的数据。至于 :start  :end :reduce 则用得比较少,最常用的就是 :step 了,

它可以让你控制 RRDtool 从那个 RRA 中取数据。

B
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 语句,这会造成极大的困扰。具体例子可以看第十一节数字报表部分。

C
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 中的数据以图表的方式显示出来。
   
   
三)选项分类

本部分我们按照官方文档的方式,把选项分成几大类,分为   

A
Time range  用于控制图表的X轴显示的起始/结束时间,也包括从RRA中提取指定时间的数据。

B
Labels 用于控制 X/Y 轴的说明文字。

C
Size 用于控制图片的大小。

D
Limits 用于控制 Y 轴的上下限。

E
Grid 用于控制 X/Y 轴的刻度如何显示。

F
Miscellaneous 其他选项。例如显示中文、水印效果等等。

G
Report 数字报表

需要说明的是,本篇当中并不是列出了所有选项的用法,只是列出较为常用的选项,如果想查看所有选项的的用法,可以到官方站点下载文档,

这里就不一一列出了,望各位见谅。


四)时间范围控制(Time Range

CODE:

[-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 之间有什么关系呢?

让我们先看 :step  –step之间的关系是如何的。

下面以 eth0.rrrd 为例,假设要绘制的时间范围 range 等于 end -start[

A
)如果 0 <   ragne < 180000 (第一个 RRA 的时间覆盖范围) ,则默认从第1RRA中取数据 :

    
如果 DEF 中给出的 :step > 300 ,例如 1000 ,则从 resolution= 1000 的或者第一个高于 1000 RRA 中挑选数据,由于 eth0.rrd 中没有

                                                    resolution = 1000 
 RRA,则 RRDtool 会从 resolution = 1200 的第2 RRA 中取数据。

    
如果 DEF 中给出的 :step <= 300 ,例如 200 ,则 RRDtool 会忽略该设定,还是从第一个 RRA 中取数据。

B
)如果 180000 < range < 720000   ,由于第一个RRA只能保存2天的数据,所以默认从第2RRA中取数据 :

    
如果 DEF 中给出的 :step > 1200 ,例如 1800,则 RRDtool 会从 resolution = 7200 的第3 RRA 中取数据

    
如果 DEF 中给出 :step<= 1200,例如 300 ,则 RRDtool 会忽略,还是从第2 RRA 中取数据

C
)如果 720000 < range <   4320000 ,则默认从第三个 RRA 中取数据 :

    
如果 DEF 中给出的 :step > 7200 ,例如 10000 ,则从第4 RRA中取数据

    
如果 DEF 中给出的 :step <= 7200 , 例如 1200 ,则忽略该值,并还是从第 RRA 中取数据

D
)如果 4320000 < range < 63072000 ,则默认从第4 RRA 中取数据 :

    
如果 DEF 中给出的 :step > 86400 ,则行为未知

    
如果 DEF 中给出的 :step <=86400 ,则从第4 RRA 中取数据

E
-S 选项可以直接控制 RRDtool 如何挑选 RRA 

例如 -S 1200 ,即使DEF 中不加 :setp ,则 RRDtool 会从第2 RRA 中取数据,即使 rang < 180000 

如果 -S  :step 同时出现,则 :step 优先。

F
DEF 中的 :start  :end 可以覆盖 –-start  –-end 的值。

    
默认情况下,如果 DEF 中不加 :start  :end ,则等于 –-start  –end

如果 DEF 中定义了 :start  :end ,则以 :start  :end 为准。

实例:使用 –-start 指定 X 轴的起始时间

CODE:

[root@dns1 bob]# rrdtool graph 1.png \ 
> --start now-120000 \ # 
表示起始时间是当前时间往前 120000 秒,也就是 33 个小时左右
> DEF:value1=eth0.rrd:eth0_in:AVERAGE \     # 
eth0.rrd 中取出 eth0_in 的数据,CF 类型为 AVERAGE
> AREA:value1#ff0000 # 
方块的形式来绘制 value1 ,注意这里是用 value1 ,不是用 eth0_in
481x154 # 
如果 RRDtool 有绘图方面的语句,则这里显示图片大小,否则为 0x0
[root@dns1 bob]#




可以看到 X 轴的文字有些是乱码,不过不要紧,你可以临时已用 env LANG=C rrdtool xxxx 来解决该问题,或者在后面用

–n 
来设定 RRDtool 使用中文字体,就不会出现这样的情况了


实例:使用 :step 从第2RRA中取数据

CODE:

[root@dns1 bob]# rrdtool graph 2.png \
> --start now-120000 \
> DEF:value1=eth0.rrd:eth0_in:AVERAGE:step=1000 \ # :step 
指定 resolution=1000 
> AREA:value1#ff0000
481x154
[root@dns1 bob]#


这里是 :step=1000,但 RRDtool 会取 :step=1200 的 第2 RRA 的数据来绘图,可以和上面的 1.png 比较,发现比较平滑。

实例:使用 –S 从第2RRA中取数据

CODE:

[root@dns1 bob]# rrdtool graph 4.png 
> -S 1200 \ # 
使用 –S 控制 RRDtool  resolution=1200  RRA 中取数据
> --start now-120000 \
> DEF:value1=eth0.rrd:eth0_in:AVERAGE \
> AREA:value1#ff0000       
481x154
[root@dns1 bob]#


可以看到和上面的图一样,说明 RRDtool 的确按照 -S 的设置从第2RRA 中取数据了

使用 –S 可以对 DEF 中所有的 DS 都使用相同的 resolution,等于在每个 DEF后都加上 :step= value  –S 的值

实例:同时使用 –S  :step

CODE:

[root@dns1 bob]# rrdtool graph 5.png 
> -S 1200 \ # -S 
指定 resolution=1200
> --start now-120000 \
> DEF:value1=eth0.rrd:eth0_in:AVERAGE:step=300 \ # :step 
指定 resolution=300
> AREA:value1#ff0000    
481x154
[root@dns1 bob]#


可以看到 5.png  1.png 是一样的,也就是说 –S 1200 并没有起作用,而是 :step=300 起作用了

实例:使用 :start  :end 只显示指定时间内的数据

CODE:

[root@dns1 bob]# rrdtool graph 1.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  
475x168
[root@dns1 bob]#




如果我们不加 :start  :end ,则效果如下 :



我们甚至可以让两个对象显示不同的时间,例如 

实例:让两个对象显示不同时间段的数据

CODE:

[root@dns1 bob]# rrdtool graph 1.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 
475x168
[root@dns1 bob]#


实例:把一段时间分为几段分别显示 :

CODE:

[root@dns1 bob]# rrdtool graph 1.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"  
475x168
[root@dns1 bob]


我们把3个小时内的数据用三种不同粗细、不同颜色的曲线画了出来。

看到了吗,out部分(红色)显示了2个小时内的流量,而in部分(绿色)则只显示了1个小时内的部分

在这里要提一点,虽然我们指定了 –-start 或者 –-end ,或者 :start , :end,但并不意味着曲线就一定会从指定的时间点开始和结束。

例如我们上面指定了 :start=now-600:end=now-300 ,也就是只显示5分钟的数据。但图表出来的效果却是10(10:05-10:15)分钟

的数据,这是因为我们挑选的时间当中不慎横垮了两个周期(10:05-10:10,10:10-10:15),所以 RRDtool 会把它们全部画出来,而不是只画其中的5分钟。
阅读(1746) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~