<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
<channel>
<title><![CDATA[运维进行时]]></title> 
<link>https://blog.liuts.com/index.php</link> 
<description><![CDATA[互联网运维与架构]]></description> 
<language>zh-cn</language> 
<copyright><![CDATA[运维进行时]]></copyright>
<item>
<link>https://blog.liuts.com/post/215/</link>
<title><![CDATA[rrdtool学习笔记]]></title> 
<author>刘天斯 &lt;liutiansi@gmail.com&gt;</author>
<category><![CDATA[rrdtool]]></category>
<pubDate>Wed, 15 Sep 2010 10:29:41 +0000</pubDate> 
<guid>https://blog.liuts.com/post/215/</guid> 
<description>
<![CDATA[ 
	<strong>一、前言</strong><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;为了做云缓存平台的技术储备，从零开始学习了rrdtool，rrdtool非常强大，刚接触会有摸不着边的感觉，尤其是一堆概念性的东西。学习的切入点便是这些概念，一一理解后你才能品尝到rrdtool的清香，首先要感谢ailms整理的“<a href="http://bbs.chinaunix.net/viewthread.php?tid=864861&extra=&highlight=rrdtool&page=1" target="_blank">RRDtool简体中文教程 v1.01</a>”，通俗易懂的概况了rrdtool的所有知识。现在整理自己在学习过程中的一些笔记。<br/><br/><strong>二、基本概念</strong><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;RRDtool是指Round Robin Database 工具（环状数据库）。Round robin是一种处理定量数据、以及当前元素指针的技术。想象一个周边标有点的圆环－－这些点就是时间存储的位置。从圆心画一条到圆周的某个点的箭头－－这就是指针。就像我们在一个圆环上一样，没有起点和终点，你可以一直往下走下去。过来一段时间，所有可用的位置都会被用过，该循环过程会自动重用原来的位置。这样，数据集不会增大，并且不需要维护。RRDtool处理RRD数据库。它用向RRD数据库存储数据、从RRD数据库中提取数据(来源百度问答 )。为了方便理解其工作原理，本人做了一个rrdtool存储结构图：<br/><a href="https://blog.liuts.com/attachment.php?fid=215" target="_blank"><img src="https://blog.liuts.com/attachment.php?fid=215" class="insertimage" alt="点击在新窗口中浏览此图片" title="点击在新窗口中浏览此图片" border="0"/></a><br/>1、<strong>DS</strong>用于定义 Data Soure 。也就是用于存放脚本的结果的变量名(DSN)。如eth0_in ,eth0_out, lo_in , lo_out 。DSN 从 1-19 个字符，必须是 0-9,a-z,A-Z 。<br/><br/>2、<strong>DST</strong>的选择是十分重要的,如果选错了 DST ,即使你的脚本取的数据是对的,放入 RRDtool 后也是错误的,更不用提画出来的图是否有意义了。<br/><br/>DST描述:<br/> A) COUNTER:必须是递增的,除非是计数器溢出(overflows)。在这种情况下,RRDtool 会自动修改收到的值。例如网络接口流量、收到的packets 数量都属于这一类型。<br/> B) DERIVE：和 COUNTER 类似。但可以是递增,也可以递减,或者一会增加一会儿减少。<br/> C) ABSOLUTE:ABSOLUTE 比较特殊,它每次都假定前一个interval的值是0,再计算平均值。<br/> D) GAUGE:GAGUE 和上面三种不同,它没有“平均”的概念,RRDtool 收到值之后字节存入 RRA 中。<br/> E) COMPUTE:COMPUTE 比较特殊,它并不接受输入,它的定义是一个表达式,能够引用其他DS并自动计算出某个值。<br/>这五种类型有什么区别？不防测试一下便知。<br/><br/>测试脚本：<br/><textarea name="code" class="python" rows="15" cols="100">
import sys,os
import time
import random
 
total_input_traffic = 0
total_output_traffic = 0
starttime=1252682400
while 1:
&nbsp;&nbsp;total_input_traffic = random.randrange(0, 5000)
&nbsp;&nbsp;total_output_traffic = random.randrange(0, 5000)
&nbsp;&nbsp;os.system("/usr/bin/rrdtool updatev /opt/rrdtool/COUNTER/eth0.rrd "+str(starttime)+":"+str(total_input_traffic)+":"+str(total_output_traffic))
&nbsp;&nbsp;os.system("/usr/bin/rrdtool updatev /opt/rrdtool/DERIVE/eth0.rrd "+str(starttime)+":"+str(total_input_traffic)+":"+str(total_output_traffic))
&nbsp;&nbsp;os.system("/usr/bin/rrdtool updatev /opt/rrdtool/ABSOLUTE/eth0.rrd "+str(starttime)+":"+str(total_input_traffic)+":"+str(total_output_traffic))
&nbsp;&nbsp;os.system("/usr/bin/rrdtool updatev /opt/rrdtool/GAUGE/eth0.rrd "+str(starttime)+":"+str(total_input_traffic)+":"+str(total_output_traffic))
&nbsp;&nbsp;if starttime>=1284218400:
&nbsp;&nbsp;&nbsp;&nbsp;break;
&nbsp;&nbsp;starttime+=300
</textarea>测试结果：<br/><span style="color: #0000FF;">a)COUNTER</span><br/><a href="https://blog.liuts.com/attachment.php?fid=209" target="_blank"><img src="https://blog.liuts.com/attachment.php?fid=209" class="insertimage" alt="点击在新窗口中浏览此图片" title="点击在新窗口中浏览此图片" border="0"/></a><br/>※为什么断断续续？原因很简单，random.randrange(0, 5000)获取的是随机值，就存在后面value比前value值小，如公式说明：(2000-3000)/300(setup)=UNKNOWN/300=UNKNOWN<br/><br/><span style="color: #0000FF;">b)DERIVE</span><br/><a href="https://blog.liuts.com/attachment.php?fid=210" target="_blank"><img src="https://blog.liuts.com/attachment.php?fid=210" class="insertimage" alt="点击在新窗口中浏览此图片" title="点击在新窗口中浏览此图片" border="0"/></a><br/>※原理同上，DERIVE除了支持是递增，也递减。<br/><br/><span style="color: #0000FF;">c)ABSOLUTE</span><br/><a href="https://blog.liuts.com/attachment.php?fid=211" target="_blank"><img src="https://blog.liuts.com/attachment.php?fid=211" class="insertimage" alt="点击在新窗口中浏览此图片" title="点击在新窗口中浏览此图片" border="0"/></a><br/>※计算公式：(3000-0)/300=100，得出初值为0的绝对值再求平均。<br/><br/><span style="color: #0000FF;">d)GAUGE</span><br/><a href="https://blog.liuts.com/attachment.php?fid=212" target="_blank"><img src="https://blog.liuts.com/attachment.php?fid=212" class="insertimage" alt="点击在新窗口中浏览此图片" title="点击在新窗口中浏览此图片" border="0"/></a><br/>※values直接入库，无作任何运行。<br/><br/>3、<strong>CDP</strong>:Consolidation Data Point 。RRDtool 使用多个PDP合并为(计算出)一个CDP。也就是执行上面的CF操作后的结果。这个值就是存入RRA的数据，绘图时使用的也是这些数据。<br/><br/>4、<strong>CF</strong>就是Consolidation Function的缩写。也就是合并(统计)功能。有AVERAGE、MAX、MIN、LAST四种分别表示对多个PDP进行取平均、取最大值、取最小值、取当前值四种类型。具体作用等到update操作时再说。<br/><br/>5、<strong>PDP</strong>:Primary Data Point。正常情况下每个interval RRDtool都会收到一个值;RRDtool在收到脚本给来的值后会计算出另外一个值(例如平均值)，这个值就是PDP;这个值代表的一般是“xxx/秒”的含义。注意，该值不一定等于RRDtool收到的那个值。除非是GAUGE，可以看下面的例子就知道了。<br/><br/>6、<strong>DST</strong>就是Data Source Type的意思。有COUNTER、GUAGE、DERIVE、ABSOLUTE、COMPUTE5种。由于网卡流量属于计数器型，所以这里应该为COUNTER。<br/><br/>7、<strong>RRA</strong>用于指定数据如何存放。我们可以把一个RRA看成一个表，各保存不同interval的统计结果<br/><br/>8、<strong>resolution</strong>就是每个RRA中两个CDP相隔的时间<br/><br/>9、什么是 CF?<br/>以第2个RRA和4，2，1，3这4个PDP为例<br/>AVERAGE:则结果为(4+2+1+3)/4=2.5<br/>MAX:结果为4个数中的最大值4<br/>MIN:结果为4个数中的最小值1<br/>LAST:结果为4个数中的最后一个3<br/><br/><strong>三、个人理解</strong><br/>1、CF(N个PDP为一个刻度单位)=CDP<br/>*只限COUNTER、DERIVE、ABSOLUTE、COMPUTE<br/><br/>2、N个PDP为一个刻度单位=CDP<br/>*只限GUAGE<br/><br/>3、xff字段如何计算？<br/>PDP/(PDP UNKNOWN数)<xff=UNKNOWN<br/><br/>4、PDP数据如何得出？<br/>COUNTER(接收Value)=PDP<br/>DERIVE(接收Value)=PDP<br/>ABSOLUTE(接收Value)=PDP<br/>COMPUTE(接收Value)=PDP<br/>*GUAGE除外<br/><br/>5、常用时间截计算(shell)<br/> A)时间截 =>日期<br/><div class="quote"><div class="quote-title">引用</div><div class="quote-content"><br/>date -d '1970-1-1 1276059000 sec utc'<br/></div></div><br/> B)日期＝>时间截<br/><div class="quote"><div class="quote-title">引用</div><div class="quote-content"><br/>date -d '2010-09-11 23:20' +%s<br/></div></div><br/><br/><strong>四、rrdtool create</strong><br/><div class="quote"><div class="quote-title">引用</div><div class="quote-content"><br/>rrdtool create Flow.rrd &#92;<br/>--start $(date -d "1 year ago" +%s) &#92;<br/>--step 300 &#92;<br/>DS:eth0_in:GAUGE:600:0:5000 &#92;<br/>DS:eth0_out:GAUGE:600:0:5000 &#92;<br/>RRA:AVERAGE:0.5:1:600 &#92;<br/>RRA:AVERAGE:0.5:6:700 &#92;<br/>RRA:AVERAGE:0.5:24:775 &#92;<br/>RRA:AVERAGE:0.5:288:797 &#92;<br/>RRA:MAX:0.5:1:600 &#92;<br/>RRA:MAX:0.5:6:700 &#92;<br/>RRA:MAX:0.5:24:775 &#92;<br/>RRA:MAX:0.5:444:797 &#92;<br/>RRA:MIN:0.5:1:600 &#92;<br/>RRA:MIN:0.5:6:700 &#92;<br/>RRA:MIN:0.5:24:775 &#92;<br/>RRA:MIN:0.5:444:797<br/></div></div><br/>RRA存储周期计算：<br/>1、RRA:AVERAGE:0.5:1:600<br/><div class="quote"><div class="quote-title">引用</div><div class="quote-content"><br/>(300s=5m)*1=5m*600=50h=(2.08天)2d<br/></div></div><br/>2、RRA:AVERAGE:0.5:6:700<br/><div class="quote"><div class="quote-title">引用</div><div class="quote-content"><br/>(300s=5m)*6=30m*700=50h=(14.58天)2w<br/></div></div><br/>3、RRA:AVERAGE:0.5:24:750<br/><div class="quote"><div class="quote-title">引用</div><div class="quote-content"><br/>(300m=5m)*24=2h*750=(64.5天)2M<br/></div></div><br/>4、RRA:AVERAGE:0.5:288:797<br/><div class="quote"><div class="quote-title">引用</div><div class="quote-content"><br/>(300m=5m)*288=1d*797=(797天)2Y<br/></div></div><br/><strong>五、rrdtool graph</strong><br/><div class="quote"><div class="quote-title">引用</div><div class="quote-content"><br/>rrdtool graph COUNTER/day.png -w 700 -h 200 &#92;<br/>-n TITLE:11:'/opt/rrdtool/wdjt.ttf' &#92;<br/>-n UNIT:8:'/opt/rrdtool/simhei.ttf' &#92;<br/>-n LEGEND:8:'/opt/rrdtool/simhei.ttf' &#92;<br/>-c SHADEA#DDDDDD &#92;<br/>-c SHADEB#808080 &#92;<br/>-c FRAME#006600 &#92;<br/>-c FONT#006699 &#92;<br/>-c ARROW#FF0000 &#92;<br/>-c AXIS#000000 &#92;<br/>-c BACK#FFFFFF &#92;<br/>-Y -X 3 &#92;<br/>-t "服务器流量统计" -v "流量" &#92;<br/>--start -1d --end now &#92;<br/>--x-grid MINUTE:12:HOUR:1:HOUR:1:0:'%H' &#92;<br/>DEF:value1=COUNTER/eth0.rrd:eth0_in:AVERAGE &#92;<br/>DEF:value2=COUNTER/eth0.rrd:eth0_out:AVERAGE &#92;<br/>CDEF:value3=value1,value2,+ &#92;<br/>COMMENT:" &#92;n" &#92;<br/>COMMENT:" &#92;n" &#92;<br/>AREA:value1#00ff00:上传 &#92;<br/>GPRINT:value1:LAST:"当前&#92;:%8.0lf"&nbsp;&nbsp;&#92;<br/>GPRINT:value1:AVERAGE:"平均&#92;:%8.0lf"&nbsp;&nbsp;&#92;<br/>GPRINT:value1:MAX:"最大&#92;:%8.0lf"&nbsp;&nbsp;&#92;<br/>GPRINT:value1:MIN:"最小&#92;:%8.0lf"&nbsp;&nbsp;&#92;<br/>COMMENT:" &#92;n" &#92;<br/>LINE2:value2#4433ff:下载 &#92;<br/>GPRINT:value2:LAST:"当前&#92;:%8.0lf"&nbsp;&nbsp;&#92;<br/>GPRINT:value2:AVERAGE:"平均&#92;:%8.0lf"&nbsp;&nbsp;&#92;<br/>GPRINT:value2:MAX:"最大&#92;:%8.0lf"&nbsp;&nbsp;&#92;<br/>GPRINT:value2:MIN:"最小&#92;:%8.0lf"&nbsp;&nbsp;&#92;<br/>COMMENT:" &#92;n" &#92;<br/>COMMENT:"─────────────────────────────────────────────&#92;n" &#92;<br/>LINE3:value3#ff8833:总流量 &#92;<br/>COMMENT:" &#92;n" &#92;<br/>HRULE:350000#ff0000:"报警值" &#92;<br/>COMMENT:" &#92;n" &#92;<br/>COMMENT:"&#92;t&#92;t&#92;t&#92;t&#92;t&#92;t&#92;t&#92;t&#92;t&#92;t&#92;t&#92;t&#92;t&#92;t&#92;t最后更新 &#92;:$(date '+%Y-%m-%d %H&#92;:%M')&#92;n" -Y &#92;<br/>COMMENT:"&#92;t&#92;t&#92;t&#92;t&#92;t&#92;t&#92;t&#92;t&#92;t&#92;t&#92;t&#92;t&#92;t&#92;t&#92;t天涯社区系统运维部开发与维护&#92;n"<br/></div></div><br/><br/>效果图：<br/><a href="https://blog.liuts.com/attachment.php?fid=213" target="_blank"><img src="https://blog.liuts.com/attachment.php?fid=213" class="insertimage" alt="点击在新窗口中浏览此图片" title="点击在新窗口中浏览此图片" border="0"/></a><br/><br/>概念说明：<br/>1、#分别是 LINE1&#124;2&#124;3,也就是线条的粗细。<br/><br/>2、"--x-grid MINUTE:15:HOUR:1:HOUR:1:0:'%H'"说明如下：<br/>#GTM:GST：控制次要格网线的位置。GTM 是一个时间单位，可以是 SECOND、MINUTE、HOUR、DAY 、WEEK、MONTH、YEAR 。GST 则是一个数字，控制每隔多长时间放置一根次要格线。例如我们要画一个1天的图表，决定每15分钟一根次要网格线，则格式为 MINUTE:15<br/><br/>#MTM:MST：控制主要网格线的位置。MTM 同样是时间单位，MST 是一个数字。接上面的例子，决定一个小时1根主要网格线。则格式为 HOUR:1<br/><br/>#LTM:LST ：控制每隔多长时间输出一个label 。决定为1小时1个 label 。则格式为 HOUR:1:0(不清楚0做什么用) ，如10 11 12 13<br/><br/>#LPR:LFM：LTM:LST只是决定了label的显示位置了，没有指定要显示什么内容。LPR指的是如何放置label。如果LPR为0，则数字对齐格线(适用于显示时间)。如果不为0，则会做一些偏移(适用于显示星期几、月份等)。至于LFM则需要熟悉一下date命令的参数，常用的有%a(星期几)、%b(月份)、%d(天)、%H(小时)、%M(分)、%Y(年)。我们决定显示小时和分，所以用%H%M，最好将'%H:%M'括起来，哪只显示小时就'%H'。<br/><br/>3、"-Y -X 0 "说明如下：<br/>a）Y轴还有一个很方便的选项就是–Y，它可以最大限度的优化Y轴的刻度，建议每次绘图都加上去。<br/>b）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显示，12则T。如果你给出1或者2，则RRDtool也可以接受，但会被“静悄悄”的改为0。下面就是一个以原值（-X0）显示原始数据，100k显示 为100000。<br/><br/>4、字体参数说明<br/><div class="quote"><div class="quote-title">引用</div><div class="quote-content"><br/>-n TITLE:12: simhei.ttf&nbsp;&nbsp;&nbsp;&nbsp;#修改top标题字体<br/>-n&nbsp;&nbsp;AXIS:8: simhei.ttf&nbsp;&nbsp;&nbsp;&nbsp;#修改X轴数据字体，如01 02 03 04...<br/>-n&nbsp;&nbsp;LEGEND:10: simhei.ttf&nbsp;&nbsp;#修改数字报表字体，如最大、最小、平均值及其它<br/>-n&nbsp;&nbsp;UNIT:8: simhei.ttf&nbsp;&nbsp;&nbsp;&nbsp;#修改Y轴标题字符，如"流量"<br/>-n&nbsp;&nbsp;WATERMARK:8: simhei.ttf&nbsp;&nbsp;&nbsp;&nbsp;#数据区右则字体，如"RRDTOOL-TOBIOETIKER"<br/></div></div><br/>5、HRULE:100000#ff0000:"报警值"<br/>绘制一根水平线，在 100k 处画一根水平线，并指出这是报警值<br/><br/>6、COLOR参数说明<br/><div class="quote"><div class="quote-title">引用</div><div class="quote-content"><br/>-c SHADEA#CCCCCC&nbsp;&nbsp;#左上边框color<br/>-c SHADEB#000000&nbsp;&nbsp;#右下边框color<br/>-c FRAME#EEEEEE&nbsp;&nbsp;#数据标志说明边框color，如"上传"左边的小正方形。<br/>-c FONT#006699&nbsp;&nbsp;&nbsp;&nbsp;#图形所有字体color<br/>-c ARROW#FF0000&nbsp;&nbsp;#两个箭头color<br/>-c AXIS#FF0099&nbsp;&nbsp;&nbsp;&nbsp;#两条箭头线color<br/>-c BACK#FFFFFF&nbsp;&nbsp;&nbsp;&nbsp;#图形背景(不含数据区)color<br/>-c CANVAS#000000&nbsp;&nbsp; #图形数据区背景color<br/>-c MGRID#ee2359&nbsp;&nbsp;#主网格线color<br/>-c GRID#FF0000&nbsp;&nbsp;&nbsp;&nbsp;#次网格线color<br/></div></div><br/>参考文章：<br/>http://bbs.chinaunix.net/viewthread.php?tid=864861&extra=&highlight=rrdtool&page=1<br/>http://segfault.in/2010/03/python-rrdtool-tutorial/<br/><br/>如大家有什么疑问或感兴趣的话题可以通过weibo与我交流：<a href="http://t.qq.com/yorkoliu" target="_blank">http://t.qq.com/yorkoliu</a><br/>Tags - <a href="https://blog.liuts.com/tags/rrdtool/" rel="tag">rrdtool</a> , <a href="https://blog.liuts.com/tags/%25E5%25AD%25A6%25E4%25B9%25A0%25E7%25AC%2594%25E8%25AE%25B0/" rel="tag">学习笔记</a>
]]>
</description>
</item>
</channel>
</rss>