一、 文件格式:
rrd
1.文件头信息区:
2.数据存储区:
RRD文件大体格式如下
数据结构: typedef struct rrd_t {stat_head_t *stat_head; ds_def_t *ds_def; rra_def_t *rra_def; live_head_t *live_head; pdp_prep_t *pdp_prep; cdp_prep_t *cdp_prep; rra_ptr_t *rra_ptr; rrd_value_t *rrd_value; } rrd_t; 下面分别详细介绍RRD头部区域和RRD数据区域: 1.RRD头区域: a) RRD头区域包括: i. 静态头部: 数据结构: typedef struct stat_head_t { char cookie[4]; //“RRD” char version[5]; //RRD版本信息 double float_cookie; // unsigned long ds_cnt; //(DS)数据源的个数 unsigned long rra_cnt; //RRA个数 unsigned long pdp_step; //数据插入间隔 unival par[10]; } stat_head_t; 说明: 重要的信息要素: ds_cnt-数据源个数:该数据值是在创建RRD文件的 时候获取到,作用为标识该RRD文件有多少个DS。 rra_cnt-RRA个数:该数据值是在创建RRD文件的时 候获取到,作用为标识该RRD文件有多少RRA。 pdp_step-间隔时间:期望多长时间接受到数据。 该数据值是在创建RRD文件的时候获取到。 举例: RRD文件命令如下所示: Rrdtool create first.rrd –start N --step 1 \ DS:fir:COUNTER:2:U:U \ DS:sec:GAUGE:2:U:U \ RRA:AVERAGE:0.5:1:60 \ RRA:MAX:0.5:60:60 \ RRA:MIN:0.5:3600:24 \ RRA:LAST:0.5: 86400:7 \ 命令说明: 命令的格式请参考相关的RRD文档,这里我们只针对 相关上面的数据结构进行解释 ds_cnt = 2; rra_cnt = 4; pdp_step = 1; ii. DS定义域: 数据结构: typedef struct ds_def_t { char ds_nam[DS_NAM_SIZE]; //数据源名称 char dst[DST_SIZE]; //数据源类型 unival par[10]; } ds_def_t; 说明: ds_nam:数据原名称。在创建的时候指定。 dst:数据源类型。创建时指定。 ds_def [0].ds_nam = fir ds_def [0].dst = COUNTER ds_def [1].ds_nam = sec ds_def [1].dst = GAUGE iii. RRA定义域: 数据结构: typedef struct rra_def_t { char cf_nam[CF_NAM_SIZE]; //CF(合并类型) unsigned long row_cnt; //RRA行数 unsigned long pdp_cnt; //pdp个数 unival par[MAX_RRA_PAR_EN]; } rra_def_t; 说明: cf_nam:合并数据的类型。(PDP数据合成CDP数据时的 类型) 例如:RRA1. Rrdtool create first.rrd –start N --step 1 \ DS:fir:COUNTER:2:U:U \ DS:sec:GAUGE:2:U:U \ RRA:AVERAGE:0.5:1:60 \ RRA:MAX:0.5:60:60 \ RRA:MIN:0.5:3600:24 \ RRA:LAST:0.5: 86400:7 \ 将60个,间隔时间为1s的数据(PDP)合成, 计算其60个中最大的作为该RRA中的数据源 (DS)的计算值进行存储。 row_cnt:RRA的行数(每一行有所有数据源的数据) pdp_cnt:该RRA在合并数据时所占用的pdp数量。 rra_def_t [0]. cf_nam = AVERAGE rra_def_t [0]. row_cnt = 60 rra_def_t [0]. pdp_cnt = 1 rra_def_t [1]. cf_nam = AVERAGE rra_def_t [1]. row_cnt = 60 rra_def_t [1]. pdp_cnt = 60 rra_def_t [2]. cf_nam = AVERAGE rra_def_t [2]. row_cnt = 24 rra_def_t [2]. pdp_cnt = 60*60 rra_def_t [3]. cf_nam = AVERAGE rra_def_t [3]. row_cnt = 7 rra_def_t [3]. pdp_cnt = 60*60*24
小节:根据上面的分析,到现在应该清楚了RRD文件中RRA和DS的具体关系了。 具体如下: 活动头部:
数据结构:
typedef struct live_head_t {
time_t last_up; //最后更新时间(秒)
long last_up_usec; //最后更新毫秒
} live_head_t;
说明:
last_up : RRD文件最后更新的时间(秒级)
last_up_usec:RRD文件最后更新时间(微秒级)
*仅一条数据
ii. PDP数据域:
数据结构:
typedef struct pdp_prep_t{
char last_ds[LAST_DS_LEN]; //目前更新rrd 文件的数据
unival scratch[10];
} pdp_prep_t;
说明:
unival scratch[10]:该变量类型是一个结构体,变量的功能就是存储计算CDP,计算多长时间没有接受到数据,等相关的信息.在实际的rrd文件中PDP的数量为DS的数量.存储的是每个DS的相关数据信息(时间,真实数据).
iii. CDP数据域:
typedef struct cdp_prep_t{
unival scratch[MAX_CDP_PAR_EN];
} cdp_prep_t;
说明:
scratch:该变量存储了与计算CDP相关的数据,如多少个PDP没有数据(与该RRA中PDP的数量有关),目前CDP数据的计算值等信息.
改CDP的数量与RRA的数量相同,同时每一条CDP数据里面包含所有的DS.简单的说就是CDP是RRA的缩小集合,目的是为计算相同RRA中下一条RRA记录做准备.
iv. RRA指针域:
typedef struct rra_ptr_t {
unsigned long cur_row; //目前不同RRA数据已经更新到的
//位置
} rra_ptr_t;
小节:
到目前位置已经清楚的看到了RRD头文件的大体面貌,至于具体的结构体内部请参考相应的代码.
RRD头文件结构图如下(根据上面创建命令绘制)
1.RRD数据区:
数据结构:
typedefdouble rrd_value_t; //RRD数据类型
rrd_value_t*rrd_value; //RRD在内存中存储形式
说明:RRD文件文件中除了RRD文件头部区域剩下的就是RRD文件数据区域.数据区域可以想象成为n*k*m 的矩阵,n为RRA的数量,k为不同RRA的行数,m为数据源DS的数量.
RRD数据区域的图形请参考上面RRA与DS的小节.