分享

RRDtool 系列连载-6 :如何从 RRD 数据库中提取数据 - RRDtool - 阿勃的 blog

 enrol 2010-12-05
RRDtool 系列连载-6 :如何从 RRD 数据库中提取数据
一)前言
RRD 是 Round Robin Database 的意思,那么是否可以象普通的数据库进行查询操作呢?

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

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

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

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

废话少说,下面开始正文

二)fetch 操作的语法

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 如何取数据

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

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

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

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

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

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

四)实际例子

实例一 :默认情况

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

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


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

[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 呢?

[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 呢?

[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 的方式

[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 的了。同理,如果想看 7200,86400 resolution的 RRA,只要把 end 部分的 ( )中的数字替换为相应的值就可以了。

[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的测试

[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的测试

[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

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多