RRDTool基础
RRDTool是基于RRD数据库来存储时间序列数据,并在需要的时候能够很轻易产生漂亮图表的一套工具包。常用于监控领域,比如监控温度、湿度、流量、CPU、内存、磁盘等等。
为什么监控数据采用RRD数据库来存储,如果采用关系数据库将其记录下来有什么问题呢?
1. 首先,监控一般是7*24小时不间断进行的,长期积累下数据量很大,来给运维带来沉重负担。
2. 其次,我们对监控数据的关注点也不一样,通常对最近的数据比较关心,而对一年前的数据就只关心一个大致趋势即可。
3. 再次,我们需要将数据转化为图表以观察变化趋势,如果数据从关系数据库取的话,数据量多、还慢,用户感知也不好。
RRD(Round Robin Database)最大的特点是以循环格式来存储时间序列格式,在持续不断插入新数据的过程中它不断将老数据淘汰掉,因此它不会积累太多的数据,RRD文件大小也会保持在一个合适的范围内。在使用RRDTool之前,首先需要建立RRD数据库,然后持续将监控数据更新至RRD,最后再将数据从RRD中取出来生成趋势图。建议RRD数据库需要涉及两个概念,一个是数据源DS,一个是循环存档RRA。下面我们就来说说什么是DS和RRA。
我们将采样来的数据放到哪里,以后出图就从那个地方(数据源)取数据。每个RRD文件可以定义多个DS,也就是一个RRD里可以同时保持多个对象的采样数据,这就方便以后我们将这些数据绘制到同一张图表中对比分析。定义数据源最重要的就是给源取个名字,以及指定其类型。
语法 DS:name:type:heartbeat:min:max
– name:数据源的名称,长度为1-19个字符
– type:数据源类型,COUNTER:累计,GAUGE:离散
– heartbeat:心跳时间,当心跳时间内仍未采样到监控数据时,将此step时间点填充为UNKONWN,一般设置为两倍step,或者取前后采样的平均值
– min:最小数据界限,在不需要限制的情况下,可以指定为U
– max:最大数据界限,在不需要限制的情况下,可以指定为U
DS里源源不断的记录着新采样回来的数据,我们会如何使用这些数据呢?当然是按照指定的时间周期来绘制走势图表了,就好比我们看股票走势图,有时看日线,有时看周线,有时看月线,有时看年线。RRA就是RRD的日线、周线、月线、年线!每个RRD可以定义多个RRA,一个5分钟为周期的RRA,一个半小时为周期的RRA,一个2小时为周期的RRA,等等。之所以定义这么多的RRA是方便以后快速出图,每个RRA都是即时更新,也就是新来一个采样数据,所有的RRA就会计算一次并保存下来,以后要出图就直接从某个RRA中取数据就好了,不需要在出图时再重新计算平均值什么的。
语法 RRA:cf:xff:steps:rows
– CF: 聚合函数,定义如何对数据进行聚合[平均:AVERAGE | 最小:MIN | 最大:MAX | 最后一笔:LAST]
– xff: 聚合时可以容忍多少个UNKOWN值,这个是UNKOWN个数和全体个数的一个比率,一般定义为0.5
– steps: RRA步长,一般为采样间隔(step)的倍数
– rows: 此RRA最多保留几份这类采样数据,注意高采样频率的RRA不要保存太多的rows,否则会影响出图性能
RRA示例图:

语法:
rrdtool create filename [--start|-b start time]
[--step|-s step]
[DS:name:type:heartbeat:min:max]
[RRA:cf:xff:steps:rows]
语法:
rrdtool update filename timestamp:datapoints
#!/usr/bin/python
import subprocess
import random
START_TIME = 1324474748
END_TIME = 1324996652
# create RRD for cpu traffic
cmd = 'rrdtool create cpu.rrd'
cmd += ' --step 300'
cmd += ' --start %d' % START_TIME
cmd += ' DS:sys:GAUGE:600:U:U'
cmd += ' DS:usr:GAUGE:600:U:U'
cmd += ' DS:idle:GAUGE:600:U:U'
cmd += ' RRA:AVERAGE:0.5:1:8640' # 5 min, save 1 month data
cmd += ' RRA:AVERAGE:0.5:6:5760' # 30 min, save 4 month data
cmd += ' RRA:AVERAGE:0.5:24:2160' # 2 hour, save 6 month data
cmd += ' RRA:MIN:0.5:1:8640' # 5 min, save 1 month data
cmd += ' RRA:MIN:0.5:6:5760' # 30 min, save 4 month data
cmd += ' RRA:MIN:0.5:24:2160' # 2 hour, save 6 month data
cmd += ' RRA:MAX:0.5:1:8640' # 5 min, save 1 month data
cmd += ' RRA:MAX:0.5:6:5760' # 30 min, save 4 month data
cmd += ' RRA:MAX:0.5:24:2160' # 2 hour, save 6 month data
cmd += ' RRA:LAST:0.5:1:8640'
subprocess.call('rm -rf cpu.rrd', shell = True)
subprocess.call(cmd, shell = True)
# update RRD
for i in xrange(START_TIME, END_TIME, 300):
sys = random.randint(0, 15)
usr = random.randint(25, 55)
idle = 100 - (sys + usr)
cmd = 'rrdtool update cpu.rrd -t sys:usr:idle %d@%d:%d:%d' % (i, sys, usr, idle)
retcode = subprocess.call(cmd, shell = True)
# draw graph
cmd = 'rrdtool graph cpu.png -h 250 -w 800'
cmd += ' --start %d --end %d' % (START_TIME, START_TIME + 86400 * 2)
cmd += ' --title "CPU Load"'
cmd += ' -v "use percent"'
cmd += ' DEF:v1=cpu.rrd:sys:AVERAGE'
cmd += ' DEF:v2=cpu.rrd:usr:AVERAGE'
cmd += ' DEF:v3=cpu.rrd:idle:AVERAGE'
cmd += ' AREA:v1#FF2626:"sys"'
cmd += ' AREA:v2#00FF00:"usr":STACK'
cmd += ' AREA:v3#C0C0C0:"idle":STACK'
subprocess.call(cmd, shell = True)

