首页 > 代码库 > RRDtool深度理解
RRDtool深度理解
RRDtool深入学习
介绍
RRDtool:Round Robin Database Tool(轮询的数据库工具)
是一种存储数据的方式,使用固定大小的空间来存储数据,并有一个指针指向最新的数据的位置。我们可以把用于存储数据的数据库的空间看成一个圆,上面有很多刻度。这些刻度所在的位置就代表用于存储数据的地方。所谓指针,可以认为是从圆心指向这些刻度的一条直线。指针会随着数据的读写自动移动。要注意的是,这个圆没有起点和终点,所以指针可以一直移动,而不用担心到达终点后就无法前进的问题。在一段时间后,当所有的空间都存满了数据,就又从头开始存放。这样整个存储空间的大小就是一个固定的数值。所以RRDtool 就是使用类似的方式来存放数据的工具。
RRDtool的详细使用:
首先,我们需要知道数据库中的数据和我们获取的数据未必是一样的,有可能一样有可能不一样,直接获取的数据对于我们来说没什么意义。我们需要理解数据结构
PDP(Primary Data Point): 主数据点
CDP(Consolidation Data Point): 聚合数据点
解析度(resolution): 指的就是时间跨度
DS(Data Source): 数据源,每一个数据源都可以对其做单独的聚合
RRDtool常用命令
rrdtool <create|update|graph|info|fetch> create: 创建新的RRD数据库文件 update: 更新新的数据到.rrd数据库里面去 graph: 使用存储在.rrd数据库里面的一个或多个RRD生成一个图片 info: 获取一个.rrd的结构信息 fetch: 获取.rrd上数据信息
rrdtool create语法介绍
rrdtool create filename [--start|-b start time] [--step|-s step] [DS:ds-name:DST:dst arguments] [RRA:CF:cf arguments] filename: 默认为.rrd为后辍的文件,名称自己随意取; --start: 指定RRDtool的第一个记录的起始时间,--start选项的值必须是timestamp的格式。 如查你想自己设定时间可以使用--start $(date -d ‘1 days ago‘ +%s) ,当然还有一种方法就是使用rrdtool fetch filename.rrd AVERAGE; --step: 就是RRDtool“期望”每隔多长时间就收到一个值; DS: 用于定义数据源; ds-name: 指定数据源的名字,随意取。必须是1到19个字符,且是a-z、A-Z、或者0-9; DST: 定义源数据类型,源数据类型分以下几种: 1、COUNTER 数据必须是递增的,保存的是相对于前面的一个值 2、GUAGE 保存原值 3、DERIVE 可增可减 4、ABSOLUTE 相对于初始值的数值 5、COMPUTE 对于COMPUTE数据源来说格式是DS:ds-name:COMPUTE:rpn-expression dst argument:数据源参数,形式是: heartbeat:min:max heartbeat: 定义在我们这个时间跨度之内,再过多长时间过期,过期的标记为unknown; min: 接收的最小值,一般我们可以都设为0; max: 接收的最大值,如果不是很清楚其最大值可以设置为U; RRA: 用于指定数据如何存放; CF: 指定数据合并方法,合并方法分以下几种: 1、average 平均值 2、max 最大值 3、min 最小值 4、last 当前值 cf arguments:数据保存,它的形式是: xff:steps:rows xff: 定义PDP中出现unknown的百分比高于设置的这个比例以后CDP也被标记为unknown; steps: 聚合函数对多少个pdp做聚合生成cdp; rows: 保存多少个聚合的cdp结果;
rrdtool update语法介绍
rrdtool {update | updatev} filename [--template | -t ds-name[:ds-name]...] [--] N | timestamp:value[:value...] -t : 改变接收数据的次序 例如,我们定义的rrdtool create test.rrd DS:ds1 DS:ds2,默认情况下我们想这个数据库里面输入值得话是:rrdtool update test.rrd N:30(DS1值):40(DS2值), 使用rrdtool update test.rrd -t ds2:ds1 40:30 把循序给颠倒; N: 表示当前时间
rrdtool info语法介绍
rrdtool info filename 用于查看filename的数据结构(filename就是rrdtool create生成的数据库文件);
rrdtool fetch语法介绍
rrdtool fetch filename [-r #] [CF] -r #: 指定#个PDP为一个数据; CF: 指定使用哪种合并函数,与rrdtool create中cf argument一样;
rrdtool graph语法介绍
rrdtool graph|graphv filename [option ...][datadefinition ...][data calculation ...][variabledefinition ...][graph element ...][print element ...] [-s|--start time][-e|--end time][-S|--step seconds] [-t|--title string][-V |--Vertical-label string ] [-w|--width pixels][-h|--height pixels][-j|--only-graph][-D|--full-size-mode] OPTION: Graph Limits [-u | --upper-limit value]: 显示数值的最大上限的值 [-l | --lower-limit value]: 显示的最低下限的值 [-r | --rigid ]: 不会自动缩放,以定义的最大值和最小值来显示 [-A | --alt-autoscale ]: 启用自动缩放,但是最大的和最小的是不能超过上面的范围 [-J | --alt-autoscale-min]: 只自动缩放最小值 [-M | --alt-autoscale-max ]: 只自动缩放最大值 [-N | --no-gridfit]: 不显示网格线 定义横轴: X-Axis [-x|--x-grid GTM:GST(定义基准网格线,前面是单位,后面是数值) :MTM:MST(定义主网格线,前面的是单位,后面的是数值) :LTM:LST(定义横轴底面的标签的单位和距离,前面是单位,后面是距离) :LPR:LFM(显示标签的显示格式)] [-x | --x-grid none ] Y-Axis [-y|--y-grid grid(刻度是什么) step(多长显示一个刻度) :label(卷标显示是什么) factor(卷标多长时间显示一个)]: [-y|--y-grid none ] [-Y| --alt-y-grid] 图片全局定义 [-c| --color COLORTAGE #rrggbb[aa]] BACK #背景色 CANVAS #画布颜色 SHADEA #左边和上边的颜色 SHADEB #右边和下边的颜色 GRID,MGRID #主网格线的颜色 FONT #字体颜色 AXIS #坐标轴的颜色 FRAME #边框颜色 ARROW #箭头的颜色 -n | --font FONTTAG(字体名字):size(大小):[font(路径)] #指定字体的参数 [-R|--font-render-mode(字体格式) {normal(正常),light(发亮),mono(粗体)}] [-a|--imgformat PNG|SVG|EPS|PDF] #图像输出格式 [-W| --watermark string ] #加水印 数据与变量 定义数据获取方式: DEF:vname(变量名,只能包含数字和字母,最长不能超过255字符)=rrdfile(rrd文件路径):ds-name(数据源名称):CF(聚合函数)[:step=step][:start=time][:end=time] CDEF:vname=RPN expression VDEF:vname=RPN expression 图片 线状图: LINE[width(线条的粗细程度,1最细的3是最粗的) :value(上面定义的变量名称)[#color(线条颜色)] [:[legend(底面的标签名称)][:STACK]] [:dashes[=on_s[,off_s[,on_s,off_s]...] [:dash-offset=offset] 面积图: AREA:value[#color][:[legend][:STACK]]
实例1:随机生成数据
1、创建一个hello.rrd数据库文件
# rrdtool create test.rrd --step 5 DS:testds:GAUGE:8:0:U RRA:AVERAGE:0.5:1:17280 RRA:AVERAGE:0.5:10:3456 RRA:AVERAGE:0.5:100:1210 # rrdtool info test.rrd filename = "test.rrd" rrd_version = "0003" step = 5 last_update = 1403544501 ds[testds].type = "GAUGE" ds[testds].minimal_heartbeat = 8 ds[testds].min = 0.0000000000e+00 ds[testds].max = NaN ds[testds].last_ds = "U" ds[testds].value = 0.0000000000e+00 ds[testds].unknown_sec = 1 rra[0].cf = "AVERAGE" rra[0].rows = 17280 rra[0].cur_row = 5294 rra[0].pdp_per_row = 1 rra[0].xff = 5.0000000000e-01 rra[0].cdp_prep[0].value = NaN rra[0].cdp_prep[0].unknown_datapoints = 0 rra[1].cf = "AVERAGE" rra[1].rows = 3456 rra[1].cur_row = 1634 rra[1].pdp_per_row = 10 rra[1].xff = 5.0000000000e-01 rra[1].cdp_prep[0].value = NaN rra[1].cdp_prep[0].unknown_datapoints = 0 rra[2].cf = "AVERAGE" rra[2].rows = 1210 rra[2].cur_row = 622 rra[2].pdp_per_row = 100 rra[2].xff = 5.0000000000e-01 rra[2].cdp_prep[0].value = NaN rra[2].cdp_prep[0].unknown_datapoints = 0
2、写一个脚本random.sh,它能自动给hello.rrd中写入数据
# vim random.sh #!/bin/bash while true; do rrdtool update test1.rrd N:$RANDOM sleep 5 done # bash -x random.sh
3、一段时间后,我们可以查看hello.rrd中的数据
# rrdtool fetch test.rrd AVERAGE -r 5 //这里我们使用每5s的解析度来显示,如果我们使用每10s呢?因为test.rrd中没有定义每10s的解析度,所以它自动会选择小于自定义的,且最靠近的解析度值显示 ... ... ... ... ... ...... 1403544585: -nan 1403544590: 2.0996768708e+03 1403544595: 1.6197283451e+04 1403544600: 1.1111383278e+04 1403544605: -nan
4、画图
1)单线条画法:
# rrdtool graph test1.png --step 5 -s 1403544590 -t TEST -v vtest DEF:vtest=test.rrd:testds:AVERAGE LINE1:vtest#FF0000:testline1 497x174
把文件复制到windows主机上查看一下吧:
2)多线条画法:
# rrdtool graph test2.png -s 1403544590 -t TEST -v vtest DEF:vtest1=test.rrd:testds:AVERAGE:step=5 DEF:vtest2=test.rrd:testds:AVERAGE:step=50 LINE1:vtest1#FF0000:testline1 LINE1:vtest2#00FF00:testline2 497x174
实例2:这里我们来记录mysql用户查询次数
# rrdtool create mysql.rrd --step 3 DS:myselect: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 # vim mysql_select.sh #!/bin/bash while true ; do select=`mysql -e "show global status like ‘com_select‘" |awk ‘/Com_select/{print $2}‘` rrdtool update mysql.rrd N:$select sleep 3 done #由于数据产生太慢,我们再写一个脚本来增大数据量,实验效果更加明显: # mysql mysql> create database testdb; mysql> use testdb; mysql> create table tb1(id int not null auto_increment primary key,name varchar(50) not null); mysql> quit # vim insert.sh #!/bin/bash for i in {1..20000}; do mysql -e "insert into testdb.tb1 (name) values(user$i)" mysql -e "select * from testdb.tb1" &>/dev/null done # bash -x mysql_select.sh # bash -x insert.sh # rrdtool graph mysql1.png -s 1403547726 -t "mysql select" -v "select per" DEF:select3=mysql.rrd:myselect:AVERAGE:step=3 LINE1:select3#FF0000:"每3秒值" 497x174
我们再扩展一下:
多条线组合在一张图片上: # rrdtool graph mysql1.png -s 1403547726 -t "mysql select" -v "select per" DEF:select3=mysql.rrd:myselect:AVERAGE:step=3 DEF:select30=mysql.rrd:myselect:AVERAGE:step=30 LINE1:select3#FF0000:"每3秒值" LINE1:select30#00FF00:"每30秒值"
为指定的线注明最大值 # rrdtool graph mysql1.png -s 1403547726 -t "mysql select" -v "select per 3/s" DEF:select30=mysql.rrd:myselect:AVERAGE:step=30 DEF:max30=mysql.rrd:myselect:MAX:step=30 LINE1:select30#FF0000:"每30秒取值" GPRINT:max30:MAX:"最大值\:%6.2lf"
本文出自 “jun.wang” 博客,请务必保留此出处http://junwang.blog.51cto.com/5050337/1430000