RRD 全称是 Round Robin Database ,即「环型数据库」。顾名思义,它是一种循环使用存储空间的数据库,适用于存储和时间序列相关的数据。RRDTool是RRD的实现工具,可用于存储和展示被监测对象随时间的变化情况。
“Round Robin”是一种存储数据的方式,使用固定大小的空间来存储数据,并有一个指针指向最新的数据的位置。存储数据的数据库的空间看成一个圆,上面有很多刻度,每个刻度上可以存储一个数值,同时有一个从圆心指向最新存储值的指针。随着时间推移,指针会绕着圆心一直移动下去,当它指向下一个刻度后,就可以在那个位置上存储一个新的数值。在一段时间后,当所有的空间都存满了数据,就又从头开始存放。这样整个存储空间的大小就是一个固定的数值。
RRD术语
ds:Data Source (ds) providing input to the database.
定义数据源(Data Source)属性,包括数据源名称 ds-name,比如我们可以给监测内存使用率的数据源命名为memory-rate。dst:Data Source Type (dst).
数据源类型(Data Source Type),常用的有以下4种数据源类型GAUGE、COUNTER、ABSOLUTE、DERIVE。pdp: Primary Data Point (pdp).
原始数据点,例如cpu的监控数据每分钟上报,每分钟上报的的数据为原始数据。cdp:Consolidated Data Point (cdp) is the long term storage format for data in the rrd database.
归档数据点,原始数据通过归档函数计算出的数据。rra:Round Robin Archive (rra). This is the place where the consolidated data points (cdp) get stored.
RRA (Round Robin Archive) 是用来定义RRD数据库归档模型cf:Consolidation Function (cf).
归档函数,表示{AVERAGE | MIN | MAX | LAST}中的一个归档函数。xff: xfiles factor.
xfiles 因子(factor),表示超过多少比率的有效 PDP 才可以计算出 CDP,通常为0.5。
数据据源类型(Data Source Type)
- GAUGE
实测值,RRD将如实记录,比如温度变化曲线
时间 | 监控值 | 存储值 |
---|---|---|
10:00 | 6℃ | 6℃ |
11:00 | 11℃ | 11℃ |
12:00 | 14℃ | 14℃ |
13:00 | 12℃ | 12℃ |
14:00 | 10℃ | 10℃ |
- COUNTER
计数值,这是一个只增不减的正整数。比如,汽车行驶里程,从汽车第一次上路开始,里程就从0开始不断增长。假设每隔30分钟监测一次汽车里程,当RRD收到COUNTER 类型的数据时,并不会像 GAUGE 类型那样直接存储,而是计算变化率:
时间 | 监控值 | 存储值 |
---|---|---|
10:00 | 12100km | Unknown |
10:30 | 12121km | 6.11m/s |
11:00 | 12135km | 7.78m/s |
11:30 | 12160km | 13.89m/s |
计算原理: (12121km - 12100km) / (10:30 - 10:00) = 11000m / 1800s = 6.11m/s
RRD对于COUNTER 类型的数据源存储的是变化率,对于上述里程表而言就是行驶速度。
注:第一个存储值为 UNKNOWN,因为没有更早的数据,所以没有变化可言)
- ABSOLUTE
ABSOLUTE 类型存储的也是变化率,假设我们正在微信和好友聊天,每五分钟我们会看一下有没有新消息,如果有的话就立即处理,这样未读提醒就会变为0,然后下一个五分钟后继续看未读新消息数,会得到这样一个监测表:
时间 | 监控值 | 存储值 |
---|---|---|
10:00 | 100条 | Unknown |
10:05 | 120条 | 0.4条/s |
10:10 | 300条 | 1条/s |
10:15 | 99条 | 0.33条/s |
计算原理:120条 / 300秒 = 0.4条/秒
- DERIVE
DERIVE类型存储的也是变化率,和 COUNTER 类型不同的是,监测值可以增长也可以下降,例如水库的水位监测:
时间 | 监控值 | 存储值 |
---|---|---|
10:00 | 1000cm | Unknown |
10:10 | 1200cm | 0.33cm/s |
10:20 | 800cm | -0.67cm/s |
10:30 | 1000km | 0.33cm/s |
计算原理: (1200cm - 1000km) / (10:10 - 10:00) = 200cm / 600s = 0.33cm/s
归档模型
RRA:CF:xff:steps:rows
- 归档函数CF
假如每秒一个原始数据上报,如果我们把每小时监测的3600个原始数据点计算一个归档平均值的话。归档函数AVERAGE。
RRD提供的归档方法有4种,除了上述的计算平均值AVERAGE方法外,还有:
1 | 计算最大值 MAX(d1,d2,d3,...dn) = 最大的那个监测值 |
xfiles因子
xff默认值为0.5,即有大于50%的有效监测值就可以在这些有效值上计算出归档值,否则这段时间内的归档值记为 UNKNOWN。steps
表示多少个PDP计算出一个CDP。例如,在每秒获取一个监测值的实例中,steps = 60 表示每60个原始数据计算一个归档数据,即一分钟一个数据点。rows
表示多少个CDP组成一个RRA。例如,在每秒获取一个监测值的实例中,steps = 60,rows=60,即一小时数据组成一个RRA。
RRD文件结构
时间 | 监控值 | 存储值 |
---|---|---|
char cookie[4] | RRD\0 | RRD文件标志 |
char version[5] | 0003\0 | RRD文件版本 |
double float_cookie | 8.642135E130 | Magic number |
unsigned long ds_cnt | 定义的DS个数 | |
unsigned long rra_cnt | 定义的RRA个数 | |
unsigned long pdp_step | pdp时间间隔 | |
unival par[10] | 保留,未使用 | |
char ds_nam[DS_NAM_SIZE] | DS的名称,DS_NAM_SIZE=20 | |
char dst[DST_SIZE] | DS的类型 | |
unival par[10] | DS的参数队列(heartbeat:min:max) | |
DS参数cnt次 | ||
char cf_nam[CF_NAM_SIZE] | CF的名称 | |
unsigned long row_cnt | 存储记录的行数 | |
unsigned long pdp_cnt | cf函数执行时,需要的pdp个数 | |
unival par[MAX_RRA_PAR_EN] | RRA的参数队列 | |
RRA参数cnt次 | ||
time_t last_up | 最后一次更新的秒数部分 | |
long last_up_usec | 最后一次跟新的微秒数部分 | |
char last_ds[LAST_DS_LEN] | 最后一次更新后ds的值 | |
unival scratch[10] | 最后一次更新后pdp的相关数值 | |
DS参数cnt次 | ||
Unival scratch[MAX_CDP_PAR_EN] | 最后一次更新后cdp的相关数值 | |
DS参数cnt次*RRA参数cnt次 | ||
unsigned long cur_row | 指向RRA当前的记录 | |
RRA参数cnt次 |
RRDTool语法
Create语法:
1 | rrdtool create filename [–start|-b start time] [–step|-s step] \ |
Update语法:
1 | rrdtool update filename [timestamp:value timestamp:value timestamp:value] |