免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12
最近访问板块 发新帖
楼主: ailms

RRDtool简体中文教程 v1.01 [复制链接]

论坛徽章:
0
发表于 2006-12-04 09:45 |显示全部楼层
RRDtool简体中文教程_9:如何使用RPN
如何使用RPN

**********************************************************************************************************************
注 :该教程参考了如下内容 :
A)官方文档 :http://oss.oetiker.ch/rrdtool/doc/index.en.html
B)abel 兄的大作 :http://bbs.chinaunix.net/viewthread.php?tid=552224&highlight=rrdtool
                http://bbs.chinaunix.net/viewthread.php?tid=552220&highlight=rrdtool
作者 :ailms <ailms{@}263{dot}net>
版本 :v1
最后修改 :2006/11/17 17:35
**********************************************************************************************************************


一)前言

RPN 代表逆波兰式(Reverse Polish Notation)。逆波兰式最早于1920年由Jan Lukasiewicz 发明,最神奇的地方是用它来表示数学表达式,

完全不需要括号。而且 RPN 不像普通的数学表达式那样,操作符在操作数的中间,而是在操作数的右边。例如 3+2 用 RPN 表示就是 3,2,+ ;

3+(2X5) 用 RPN 表示就是 3,2,5,x,+ 最后运算的部分(加法部分)的操作符放在最后,乘号放在前面,表示先执行 2 x 5 ,在把结果和3相加。

在 RRDtool 中,RPN 还可以用来表示 if-then-else 关系。这点在绘图中很有用。例如你要看 eth0 接口在一天当中流量 ≥ 10Mb/s 的部分,“隐藏”

其他低于 10Mb/s 的部分,则可以用到这个功能。

二)操作符

什么是 RPN

A)RPN 是 Reverse Polish Notation 的缩写,是用于表示算术运算和逻辑运算的一种语法格式。

B)RRDtool 的 CDEF 语句中就经常使用 RPN 来对 DEF 取出来的数据进行运算。

C)RPN 的特点是操作数和操作符出现的顺序和运算的顺序一致,这样就不需要使用括号了

D)RPN 的格式是 <value1>,<value2>,<operator> ,[<value1>,<value2>,<operator>]… 可以看出是操作数在前,操作符在后的格式

E)RPN 需要提到堆栈的概念(stack)。堆栈是用来存储操作数和操作符的。

F)当堆栈中压入(push)一个操作符时,就从堆栈中取出(pop)所需要的操作数进行计算(根据操作的不同pop出不同数量的操作数)。
  
     结果再返回(push)堆栈,最终整个 RPN 应该只返回一个值,或者说堆栈中只有一个元素

G)在 CDEF 中书写 RPN 操作符,要一律以大写的格式出现

H) RPN 中,如果某个部分的运算结果非 0,则被认为是 true ,只有 0 才被认为是 false

三)RPN 操作符的分类

A)布尔操作符 :GT、GE、LT、LE、EQ、NE、

B)特殊值比较符 :UN、ISINF、

C)条件操作符 :IF

D)比较操作符 :MIN、MAX、LIMIT

E)算术操作符 :+ 、-、*、/、%、SIN, COS, LOG, EXP, SQRT、FLOOR, CEIL、ATAN、ATAN2、DEG2RAD, RAD2DEG

F)数据集操作符 :所谓数据集(sets),就是指多个数据。SORT、REV、AVG、TREND

G)特殊值 :UNKN、INF、NEINF、PREV、COUNT

H)时间操作符 :NOW、TIME、LTIME

I)堆栈操作符 :POP、DUP、EXC

四)RPN 操作的结果

A)布尔操作符 :从堆栈中 pop 出两个元素,并根据比较结果返回 0 (false) 或者 1 。任何同 UNKNOWN 或者 INF 、NEINF 比较的都为 0

B)特殊值比较符 :从堆栈中 pop 出1个元素,并同 UNKNOWN 或者 INF、NEINF 比较。结果为 0 或者 1

C)条件操作符 :从堆栈中pop出3个元素,如果最后pop出的那个元素不为0(条件部分为 true),则第2次 pop 出的那个元素被重新入栈(then部分);

     否则第一次pop出的元素重新入栈(else部分)。结果为 then 部分或者 else 部分返回的值,不一定为0或者1

D)比较操作符 :

     对于 MIN/MAX 操作符来说,从堆栈中 pop 出两个操作符,并把较大/小的那个重新入栈。如果其中有一个 unknown ,则结果为 unknonw

     对于 LIMIT 操作符来说,先从堆栈中 pop 出2个操作数,作为边界的定义;再 pop 出1个操作数,比较该操作数是否落在前面定义的范围内。
     
     如果是则把最后 pop 出的那个元素重新入栈;否则把 UNKN 值入栈;注意,是 UNKN ,不是 0

E)算术操作符 :根据操作符 pop 出所需数量的操作数,并把算术运算的结果重新入栈

F)数据集操作符 :

    对于 SORT、REV 来说,先从堆栈中 POP 出一个元素,该元素的值就是下面要 pop 出的元素的数量。然后对堆栈从上到下的若干个元素
   
   由第一次 pop 的出的那个元素的值决定)进行排序/反向排序。结果再重新入栈。

   注意 :由于堆栈的特点是后进先出,所以要操作的元素是从SORT操作符往左方向计数。例如v1,v2,v3,v4,3,SORT是对 v2~v4 排序,
   
            不是对 v1~v3 排序。  这点在书写 RPN 时要特别注意。

   注意 :SORT 操作是最小值在堆栈的最顶部;REV 则相反,最小值是在堆栈的最顶部。

   对于 AVG 操作来说,同样是先 pop 出1个元素,并按照指定的数量对后续的若干个操作数进行操作,但结果只有一个数值,并入栈。


G)特殊值 :

    UNKN 表示压入一个 UNKN 值;INF、NEINF 分别表示把 INF、NEINF 值压入堆栈

H)时间操作符 :

   TIME 返回当前所提取的记录的 timestamp ,注意 TIME 直接返回当前记录的 timestamp ,不用任何参数

   NOW 返回当前时间,同样 NOW 不用任何参数

I)堆栈操作符 :

   POP :弹出堆栈的最顶部的那个元素

  EXC :交换堆栈顶部的第一个和第二个元素的值

五)如何阅读 RPN

A)首先按照从左到右的顺序,找出第一个 RPN 操作符,并根据上一节的内容,对相应的操作数进行操作

B)操作结果分成两种 :

        如果是一个值,直接替换掉该部分 RPN

        如果是多个值(数据集操作,但 AVG 操作只返回一个值),则结果可能为多个数值。则把这若干个数值用 ‘,’ 隔开,替换原来那部分 RPN

C)如此循环,一直到整个 RPN 只返回一个值为止

六、RPN 实例

A)布尔型操作符 :2,1,GE 表示 2>=1 ;

B)特殊值比较符 :mydata,UN 表示 mydata == UNKNOWN

C)条件操作符 :mydata,UN,0,mydata,IF 表示如果 mydata 等于 UNKNOWN ,则返回 0;否则还是返回 mydata 本身

D)比较操作符 :mydata,20,MAX 表示返回 mydata,20 这两个数值中较大的一个;alpha,0,100,LIMIT 表示测试 alpha 的值是否小于等于0,大于等于100;

E)算术操作符 :1,2,- 表示 1-2=-1

F)数据集操作符 :

    v1,v2,v3,v4,v5,4,SORT 表示对 v1~v4 进行正向排序,结果堆栈中还是有5个元素;

    v1,v2,v3,v4,3,AVG,+,2,/ 表示对 v4,v3,v2 进行求平均值,并把结果入栈。假设v2~v4的结果为 k ,则为 v1,k,+,2,/ 也就是返回 (v1+k)/2

G)特殊值 :mydata,0,GT,UNKN,mydata,IF 表示如果 mydata 大于 0则返回 UNKNOWN ,否则还是 mydata

H)时间操作符 : TIME,`date –d “2006-10-01 10:00” +%s`,GT,0,1,IF 表示如果当前记录的采集时间是在 2006-10-01 10:00 之后就返回1,否则返回 0

I)堆栈操作符 :POP 就立即弹出第一个元素


七)如何表示 AND、OR 关系

A)我们知道 RPN 表达式的值除非0,否则都认为是 true

B)我们可以利用 加法操作和乘法操作来实现 OR 和 AND 的逻辑关系;如果两个 RPN 表达式的值相加不等于0,就一定为 true ;

     如果两个 RPN 表达式的值相乘不等于0,就一定为 true

C)AND 关系的例子 :例如要比较某个值(15,9)是否在特定范围内可以用 :

    15,10,GT,15,20,LT,* ,结果就是(15>10)*(15 < 20)= 1 * 1 =1 ,所以为 true

     9,10,GT,9,20,LT,* ,结果就是 (9 >10)* ( 9 < 20)= 0 * 1 =0 ,所以为 false

D)OR 关系的例子:同上例如要比较某个值(7,15)小于10,或者大于20:

     7,10,LT,7,20,GT,+ ,结果为 (7 < 10)+ (7 > 20) = 1+0 = 1,所以为 true

     15,10,LT,15,20,GT,+ ,结果为 ( 15 < 10) + ( 15 > 20) = 0 + 0 =0 ,所以为 false

E)不过使用 + 需要注意一个地方 :相加的双方都必须是正数,否则可能出现问题,例如一个正数(-5,true)和另外一个正数(5,true)相加为 0(false)

        如果是按照 OR 的关系,应该是 true 的,但结果变成0(false),所以在使用 + 来表示 OR 的关系时,要注意该问题

F)使用 * 则没有该问题了,正数 * 负数 = 负数 (true)。所以如果遇到 OR 关系的时候,可以转换为 AND 关系来计算。

     例如要表达 (x < a) OR ( x > b) 的关系,可以改为 (x >a) AND ( x < b ) ,诀窍就是把比较操作符调反方向,把 + 改为 *

八)实例

实例1:例如要看 eth0的总流量,可以用如下的定义
                       

  1. DEF:value1=eth0.rrd:eth0_in:AVERAGE \
  2. DEF:value2=eth0.rrd:eth0_out:AVERAGE \
  3. CDEF:value3=value1,value2,+ \
  4. AREA:value3#ff0000:”total”
复制代码


实例2 :假设我们要把 eth0 和 lo 的流入流量相加,得出总的流入流量


  1. DEF:value1=eth0.rrd:eth0_in:AVERAGE \
  2. DEF:value2=lo.rrd:lo_out:AVERAGE \
  3. CDEF:value3=value2,UN,0,value2,IF \
  4. CDEF:value4=value1,value3,+ \
  5. AREA:value4#00ff00:”total in”
复制代码

由于 lo.rrd 一直没有数据插入,所以一直都是 NaN ,如果直接把 value1 和 value2 相加,由于 value2 是 UNKNOWN,

所以相加的结果也是 UNKNOWN 。图表上将什么都不显示,所以需要对 value2 进行判断,如果 value2 的值 UNKNOWN        (value2,UN),

则返回0,否则返回 value2 本身。然后把这个值赋予变量 value3 ,最后把 value1 和 value3 相加,才得出真正入流量

实例3 :只看 eth0 中流量大于 10Mb/s 的部分,其余不看
                       

  1. DEF:value1=eth0.rrd:eth0_in:AVERAGE \
  2. DEF:value2=eth0.rrd:eth0-_out:AVERAGE \
  3. CDEF:value3=value1,1000000,GT,value1,UNKN,IF \
  4. CDEF:value4=value2,1000000,GT,value2,UNKN,IF \
  5. AREA:value3#00ff00:”traffic_in \> 10M\/s” \
  6. AREA:value4#ff0000:”traffic_out \> 10Mb\/s”:STACK
复制代码



实例4 :只绘制特定时间段(在 2006/11/29 10:30 ~ 2006/11/29 12:30)的数据


  1. DEF:value1=eth0.rrd:eth0_in:AVERAGE \
  2. DEF:value2=eth0.rrd:eth0_out:AVERAGE \
  3. CDEF:value3=TIME,$(date –d ‘2006-11-29 10:30’ +%s),GT,TIME,$(date –d '2006-11-29 12:30' +%s),LT,*,value1,UNKN,IF \
  4. CDEF:value4=TIME,$(date –d ‘2006-11-29 12:30’ +%s),GT,TIME,$(date –d '2006-11-29 13:30' +%s),LT,*,value2,UNKN,IF \
  5. AREA:value3#00ff00:”traffic_in” \
  6. AREA:value4#ff0000:”traffic_out”:STACK
复制代码



九、完结

相信到目前为止,大家对 RRDtool 的认识应该更深了吧。一定要多做实验,这样才能做到熟能生巧,灵活应用。

其实剩下的还有 xport、dump、restore、resize、tune、rrdcgi 几个操作没讲,而且有一些应用经验方面的东西也没有提到,

不过想要全部写出来,可能太耗时间和精力了,这些东西足足写了我2个星期才写完。中间还要不断的做实验以验证正确性,怕误导了大家。

如果需要的话,可以自己下载官方文档学习,或者能有热心的朋友补充就更好了,^_^ 。

十、 本人的一点学习体会

  本人从开始看 RRDtool 官方文档到开始写这篇教程,差不多用了2个月。 RRDtool 比学习 MRTG 难多了,资料少,RRDtool 的中文资料目前就只有 abel

兄写的那一篇教程,如果没有实际的上机操作,是不可能看懂的,所以 abel 兄也特别交代这点。如果只一心想速成,到头来反而吃亏的是自己。

   象sendmail、bind 这些服务器的配置,随便在 google 上都可以搜到一大把所谓的“快速入门”,很多人也都照着做了。但明明别人可以的,为什么轮到自己
   
却失败呢?相信这是很多人心中曾有的郁闷经历。其实归根到底就是基础的问题,再深入一些就是学习心态的问题。“不积跬步,无以至千里;不积小流,无以成江海”。

配置一个服务器并不是照抄配置就可以的。环境的不同,需求的不同这些因素都要考虑在内。怎么可能做到完全一样呢?同一个语句换个环境可能就不行了。所以我很

少看那些所谓的快速入门,要么看 manual ,要么看书(说到这里,感觉 O’Reilly 的书真是不错!^_^),如果是象 RRDtool这种的,就只好看官方文档了。
   
  学习的同时也要注意选择好的教材。有时候一本好书能带给无穷的好处。这点在我第一次看 O’Reilly 的 《dns & bind 4th》就有感觉,老外的书很注重循序渐进,
  
通常他们都是从某个实际工作环境的一个小例子说起,逐步引入各个命令、配置语句。然后随着需求的壮大,不断引入新的内容,最后形成一个总体。这样看完后会心中会

有一个整体的框架和概念。不象国内一些书,毫不顾及条理,一上来就讲语法、命令,搞得读者很快都没有兴趣。这样的书可谓害人不浅。

   同时也建议大家读英文原版的书。为什么呢?虽然中文的看起来快一些,但学习不是竞走比赛。不是比谁看的快,而是比谁学的牢。英文书的词汇其实都是专业词汇,

只要看多了,自然记住了。实在记不住,可以用金山词霸等工具辅助。俺的英文水平只有二级,但并不妨碍我看书。况且看英文书,有一个“英文→中文”的转换的过程。就

是揣摩作者这句话的含义,或者说这句话应该如何翻译好。有些人觉得这个没有什么,但我觉得这个过程是你弄清作者思想的重要步骤。在你不断的揣摩中,可能会有不同

的理解,直到你认为这是最正确的那一种解释为止。如果是看中文书,可能会由于惰性,比较容易就接受作者的想法,而失去这个主动我思考的过程。

  一时有感而发,胡乱写了一通,请各位朋友见谅了。

  书山有路勤为径,学海无涯苦做舟!

   愿以该座右铭和各位有志于Linux的朋友一起共勉!

  2006/12/2 22:23
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP