RRDtool深度理解

                           RRDtool深入學習

介紹

RRDtool:Round Robin Database Tool(輪詢的數據庫工具)

    是一種存儲數據的方式,使用固定大小的空間來存儲數據,並有一個指針指向最新的數據的位置。我們可以把用於存儲數據的數據庫的空間看成一個圓,上面有很多刻度。這些刻度所在的位置就代表用於存儲數據的地方。所謂指針,可以認爲是從圓心指向這些刻度的一條直線。指針會隨着數據的讀寫自動移動。要注意的是,這個圓沒有起點和終點,所以指針可以一直移動,而不用擔心到達終點後就無法前進的問題。在一段時間後,當所有的空間都存滿了數據,就又從頭開始存放。這樣整個存儲空間的大小就是一個固定的數值。所以RRDtool 就是使用類似的方式來存放數據的工具。


RRDtool的詳細使用:

首先,我們需要知道數據庫中的數據和我們獲取的數據未必是一樣的,有可能一樣有可能不一樣,直接獲取的數據對於我們來說沒什麼意義。我們需要理解數據結構

wKioL1OoT-KC6YP3AADC5HX_yW8170.jpg

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主機上查看一下吧:

wKioL1OoaPazJ4LMAAEXQ31VRmo942.jpg

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

wKiom1OoapmhTZ5eAAE3R1ay-E0511.jpg


實例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

wKiom1OocmzCzen5AADd-ZLYbK0229.jpg

我們再擴展一下:

多條線組合在一張圖片上:
# 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秒值"

wKioL1Ooc0OxrEK-AADwwGHV4FQ631.jpg

爲指定的線註明最大值
# 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"

wKioL1Ooc_2gv11KAADptPhshGc113.jpg





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章