分类: 系统运维
2011-11-24 18:26:02
RRD——round robin database
DS——data source
DST——data source type
RRA——round robin archive
CF——consolidation function(合并/归并函数)
PDP——primary data point(基本数据点)
CDP——consolidation data point(合并/归并数据点)
RPN expression——逆波兰表达式
DEF——Definition
CDEF——Calculation Define
confidence band —— 【统计数学】置信带
confidence bound —— 置信界限
wrap around —— 环绕,其实它的意思就是饼状数据库的数据覆盖满一圈,马上即将有数据丢失发生
季节 —— 具有周期规律的时间段,统称为季节
其他相关数学术语 —— 请参考统计学原理中的描述。
文件名:RRD数据库文件名应当以.rrd作为扩展名。尽管RRDtool可以接受任何文件名。
创建语法格式:
rrdtool create filename [--start|-b start time] [--step|-s step] [DS:ds-name:DST:dst arguments] [RRA:CF:cf arguments]
此filename首次创建时,由于没有数据,db的数据内容区将会被NaN填满
--start|-b start time 缺省值是now-10s,rrdtool不接受任何这个时间点前的数据更新
--step|-s step:缺省值是300s
2.1 DSdata sources (DS)的命名:1-19个字符长度,这里的字符指的是【a-zA-Z0-9_】
DST是ds的类型(DS type)类型有以下5种:
GAUGE:无规律的单纯的某点的值,如温度值,人的数量。存入db时就是该值。
COUNTER:单调递增的值,如一个路由器的ifInOctets数(端口的in的字节数)。存入db时是增加的值(即差值)。
COUNTER数据源假设计算机永远不会减小,除非计数器溢出。Rrd的update功能可能导致溢出。计算机是按照每秒的频率存储的。当计数器溢出时,RRDtool会检查该溢出是否会发生在32位或64位边界,并且相应的把合适的值加入结果中。
DERIVE:存放该数据源从过去到现在的的差异线。非单调,体现的是变化 率,这对于GAUGE类型非常有用。比方,它可以迎来度量进出一个房间的人数比率。DERIVE的工作模式=COUNTER+无溢出检查。因此,如果你的 计数器在32或64位不会复位,你可以使用min=0的DERIVE类型。
如果你不允许偶尔发生的、某个计数器的合法回绕复位而造成的错误,而要用‘unknowns’来对表示所有计数器的合法回绕(wrap)和复位 (reset),你就要使用min=0的DERIVE类型。否则,使用具有合理max值的COUNTER类型,会为所有的合法计数器回绕(wrap)返回 正确的值。
对于一个步长为5分钟的32位计数器,计数器回绕复位的错误概率大约为:每1Mbps的最大带宽发生概率为0.8%.注意这等价于100Mbps接口的 80%,因此对于高带宽接口和32位计数器,最好使用带有min=0的DERIVE。如果你使用的是64位计数器,只有任何最大值的设定可以避免计数器回 绕的错误发生的可能性。
ABSOLUTE:读取后马上复位的计数器。用于易于溢出的快速计数器。因此,不要常规地读取他们,你需要自每次读取后确认在下一次溢出前有一个最大的有效时间。该类型的另外一个用途比如是你需要累积上次更新以来的信息数目。
COMPUTE:用于存放对RRD中的其他数据源进行公式计算的结果。该数 据源在更新时不需要提供数值,它是根据rpn表达式定义的公式从数据源的PDPs中计算出来的PDP(Primary Data Point)。归并功能会被应用到COMPUTE数据源的PDPs上(那就是说rpn表达式仅仅应用于一般的PDPs)。在数据库软件中,此类数据集用 ‘虚拟’或‘计算’列表示。
前4种类型的DS的定义语法为:
DS:ds-name:GAUGE | COUNTER | DERIVE | ABSOLUTE:heartbeat:min:max
第5种类型的DS定义稍微有些区别,定义格式如下:
DS:ds-name:COMPUTE:rpn-expression
Heartbeat:心跳定义了在两次数据源更新之间,在将数据源的数值被确定为UNKNOWN前所允许的最大秒数。
Min和max值:越界则赋予UNKNOWN,不清楚或者不知道该设置多少,那么就set为U。注意min和max总是特指处理的DS值。对于一个流量计数器类型——COUNT型的DS来说,就是预期中从该设备获取的最大和最小数据率。
如果有可用的min/max的值信息,一定要设置min和max属性。这可以帮助RRDtool在更新时对提供的数据进行健壮检查。
Rpn表达式定义了由同一个RRD库的其他数据源的计算而来的、某个COMPUTE数据源的PDPs计算公式。这于graph命令的CDEF参数一 样。对于COMPUTE数据源,不支持以下RPN操作符:COUNT、PREV、TIME、和LTIME。在定义RPN表达式时,COMPUTE数据源只 能够引用在create命令中列出的数据源。这于CDEF的限制是一样的,CDEF只能够引用在同一个graph命令中前面定义的DEFs和CDEFs。
2.2 RRA语法及描述RRA:CF:cf arguments
rrd的目的是在rra中存储数据,注意这里的a是archives的意思,一个归档有大量的数据值或者每个已定义的数据源的统计,而且它是在一个RRA行中被定义的。说白了就是数据值存储的格式。
当数据进入RRD数据库时,首先填入到用-s选项所定义的步长插槽中的数据,这样就成为一个pdp(Primary Data Point)值。
该数据也会被用该归档的CF(合并/归并函数)进行处理。可以把各个PDPs通过某个聚合函数进行归并的归并函数有这样几种:AVERAGE、MIN、MAX、LAST等。这4种分别表示对多个PDP 进行取平均、取最大值、取最小值、取当前值四种类型。
这些归并函数的RRA命令行格式为:
RRA:AVERAGE | MIN | MAX | LAST:xff:steps:rows
这里说2个概念:pdp大家都知道了是表示基本数据点(注意这是采集时),但是写入rrd数据库的却是归并后的数据点(CDP)。
Xff的含义:官方说的很含糊,它是xfile factor的缩写,其实它的意思是——值位于0-1之间,是个比率,它定义的就是把PDP换算成CDP时的一种特殊情况(UNKNOWN)的处理。比如xff是0.5,就是说10个PDP中,如果其中有大于或等于5个UNKNOWN的情况出现,那么CDP合并后的结果就是UNKNOWN,否则就是有效PDP的平均值。如果不巧你就2个PDP,要合并成1个CDP,那么有1个PDP为UNKNOWN的话,合成后的CDP就是UNKOWN。
Steps:定义多少个PDP可以用来构建归并的数据点(CDP)。
Rows:定义在数据库的一个RRA归档中保留多少次的生成数据值。它记录该rra域中最大可以存多少笔数据。显然一定要大于0
2.3异常行为预测——霍尔特-温特斯(Holt-Winter)预测
霍尔特-温特斯(Holt-Winter)预测——异常行为检测
除了合并函数外,还有一套特殊的函数使得rrdtool能提供平滑数据(通过霍尔特-温特斯预测算法)、置信带和数据源时间序列里的标记异常行为:
简单的理解是:
HWPREDICT——季节迭加模型
MHWPREDICT——季节乘积模型
Alpha,Beta,Gamma——平滑系数,缺省状态是由系统自动给定,也可自己指定
这些RRA定义和合并函数的区别有这样几个地方:
首先,每个基本数据点(PDP)更新时,每个RRA都会一次全部更新
其次,这些RRAs是相互依赖的。
(1)对一般的实时置信界限,匹配一组SEASONAL, DEVSEASONAL, DEVPREDICT和HWPREDICT或MHWPREDICT二者之一。
(2)一般的基本数据点(PDP)平滑值需要一SEASONAL RRA和HWPREDICT、MHWPREDICT二者之一。
(3)异常行为检测需要FAILURES, DEVSEASONAL, SEASONAL和HWPREDICT、MHWPREDICT二者之一。
预知的、平滑的值被存在HWPREDICT或 MHWPREDICT RRA中。HWPREDICT、MHWPREDICT实际上是霍尔特-温特斯方法的2个变种,它们是可互换的,二者都会尝试将数据分解成3个部分:一个基 准线(a baseline,也可译为基准水平)、一个趋势(a trend)和一个季节系数(a seasonal coefficient)。HWPREDICT将它的季节系数和基线相加形成一个预测。但是MHWPREDICT是将它的季节系数和基线相乘形成一个预 测。
当基准线在季节期间发生显著的变化时,不同之处是很明显 的,HWPREDICT将保留常数作为基准性的变化来预测季节性因素,但是MHWPREDICT是根据基准线增大或缩小的比例来预测季节性因素。正确方法 的选择取决于你的数学模型。简单起见,这次讨论的剩下部分将特指HWPREDICT,但MHWPREDICT可能取代它的位置。
预测偏差被存储在DEVPREDICT中(可以认为一个标准偏差是可以缩放产生一信心带),失败的RRA信息存储为二元指标,用一个1来标志索引观察为失败,就是说,在前面的窗口观察达到越过置信界限的数量或超过指定的阀值。使用这些rra来画出置信界限和故障显示的一个例子见
SEASONAL和DEVSEASONAL类型的RRA,存储季 节系数是分别是为了Holt-Winters 预测计算和季节性的偏差,在季节性周期中,每个观察时间点有一个入口,例如假设PDP(primary data points)是每5分钟采集一次,季节性周期是1天,那么SEASONAL和DEVSEASONAL二者都会有288行(数据)。
为了简化新手的创建,除了支持显式创建HWPREDICT, SEASONAL, DEVPREDICT, DEVSEASONAL,和FAILURES类型的RRAs,rrdtool create命令也支持隐式创建后4种。当HWPREDICT被单独指定时,最后那个参数rra-num是可以省略的。
Rows指定了预先RRA回 绕的长度,记得这些rras里PDP(primary data points)和入口间有一个一对一的对应关系。对HWPREDICT的合并函数(CF)而言,rows应该比seasonal period(季节性时期)大,如果DEVPREDICT RRA是隐式创建,rows的缺省值和HWPREDICT的rows参数是一样的,如果FAILURES RRA是隐式创建,rows将会被设置成seasonal period(季节性时期)参数,当然,如果这些预设值是不够的,而且不满足创建者的意愿,rrdtool会自动调整命令是可用的,以避免显式创建指定其 他功能的RRAs
seasonal period指定了季节期间的PDP数,如果SEASONAL和DEVSEASONAL是隐式创建,这个参数对于那些RRAs是由HWPREDICT自动设定为指定的值,如果他们是显式创建的,创建者应该检验合适所有这三个季节期间的参数的一致性。
Alpha是霍尔特-温特斯预测算法中的拦截(或基准)系数的适应参数,见rrdtool的算法描述,alpha必须介于0和1之间,值接近1,意味着比较近期的观测的baseline(基准线)部分的预测比重更大,值接近0,意味着过去的历史的基准线(baseline)部分的预测比重更大。
Beta是霍尔特-温特斯预测算法中斜坡(或线性趋势)系数的适应参数,Beta也必须介于0和1之间,在预测线性趋势方面。和Alpha发挥同样的作用。
Gamma是霍尔特-温特斯 预测算法(HWPREDICT)中的季节性系数的适应参数,或者指数平滑更新的季节偏差的适应参数,它必须介于0和1之间,如果SEASONAL和 DEVSEASONAL类型的RRAs是隐式创建的,它们将拥有相同值的gamma:指定的值为HWPREDICT的alpha参数,请注意,因为季节性 周期期间,每个时间点有一个季节性系数(或偏差),适应率比baseline(基准线)慢的多,当观察的值发生在季节性周期相应的系数的偏移内,每个季节 系数只会更新(或适应)。
如果SEASONAL和DEVSEASONAL类型的RRAs是显式的创建,二者的gamma不必都一样,注意gamma也能被rrdtool的tune命令改变。
smoothing-window指 定了一个季节里的每个点都应该被平均,默认情况下,smoothing-window的值是0.05,这意味着通过它与相邻点的(seasonal period*0.05)的值的平均,SEASONAL和DEVSEASONAL中的每个值会偶尔被取代。设置平滑窗口为零将disable running-average smoother(大概之意就是平滑被禁止)。
Rra-num规定RRAs之间的联系,如果HWPREDICT被单独指定,而其它的RRAs是隐式创建,便无须担心这个参数,如果RRAs是显式 创建的,那就需要仔细留意这个参数。对每个包含这个参数的RRA而言,在一RRA和另一RRA间存在着依赖关系。在RRA的创建顺序(就是说,他们显示在 create命令里的顺序)中,rra-num参数是以某一指定索引为基准(1-based index)的。每个RRA和依赖的RRA需要rra-num参数列在这里:
Threshold(阀值)是一个窗口内构成了故障的违反的最小数量(置信界限外的观测值),如果FAILURES RRA是隐式创建的,那么默认值是7。
Window length是窗口中的时间点的数量,指定一个整数,大于或等于threshold(阀值),小于或等于28。这个窗口的时间间隔取决于PDP(primary data points)的间隔,如果FAILURES RRA是隐式创建的,那么默认值是9。
2.4 HEARTBEAT && STEP这儿有个Don Baarda关于rrdtool内部工作机制的解释,它可以帮助你理解为什么所有的UNKNOWN数据出现在你的数据库的原因。
Heartbeat定义了samples或updates之间的最大可接受间隔,如果samples之间的间隔比heartbeat小,那么平均率(平均率的计算见下段)将 被计算并应用到这个interval(间隔区间)。如果samples之间的间隔比heartbeat大,那么整个interval(间隔区间)被认为是 UNKNOWN请注意,还有其他的东西,可以作出采样间隔为“UNKNOWN”,比如比率超限,或者一个sample被明确标记为UNKNOWN。
一个PDP的step间隔期间的KNOWN的比率被用来计算这个PDP的平均率, 如果总UNKNOWN的时间占了一半以上的“step”,这意味着整个PDP被标示为UNKNOWN,这意味着在一个单一的PDP的“step”中,一个 混合了KNOWN和UNKNOWN的次数,可能会或不会添加了足够的KNOWN的次数使得它成为一个KNOWN的PDP。
相对于PDPs间的step间隔,Heartbeat可以是短的 (不通常的做法)或可以是长的(典型的做法),一个短的heartbeat意味着每个PDP需要多个采样样例(samples),如果你没有得到这些(采 样样例),那么标记该PDP为unknown。一个长的heartbeat可以跨多个step,这意味着它是可以接受从一个单一的采样样例计算多个PDP 的值。一个极端的例子,step为5分钟,heartbeat是1天,在这种情况下,一个单一的采样样例,每天将导致所有的PDPs整个一天的时间期间内 都被设成相同的平均率。—— Don Baarda
2.5一些例子显然:超过(大于)600秒如果未接受到任何新的数据,那么该temperature将被置为UNKNOWN。最小值-273,最大值5000
EXAMPLE2这是一个路由器流量,可以发现我们定义了异常行为检测,我们建好后info看一下:
filename = "monitor.rrd"
rrd_version = "0003"
step = 300
last_update = 1219743092
ds[ifOutOctets].type = "COUNTER"
ds[ifOutOctets].minimal_heartbeat = 1800
ds[ifOutOctets].min = 0.0000000000e+00
ds[ifOutOctets].max = 4.2949672950e+09
ds[ifOutOctets].last_ds = "U"
ds[ifOutOctets].value = 0.0000000000e+00
ds[ifOutOctets].unknown_sec = 92
rra[0].cf = "AVERAGE"
rra[0].rows = 2016
rra[0].cur_row = 352
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 = "HWPREDICT"
rra[1].rows = 1440
rra[1].cur_row = 1411
rra[1].pdp_per_row = 1
rra[1].alpha = 1.0000000000e-01
rra[1].beta = 3.5000000000e-03
rra[1].cdp_prep[0].intercept = NaN
rra[1].cdp_prep[0].slope = NaN
rra[1].cdp_prep[0].NaN_count = 1
rra[2].cf = "SEASONAL"
rra[2].rows = 288
rra[2].cur_row = 72
rra[2].pdp_per_row = 1
rra[2].gamma = 1.0000000000e-01
rra[2].cdp_prep[0].seasonal = NaN
rra[3].cf = "DEVSEASONAL"
rra[3].rows = 288
rra[3].cur_row = 34
rra[3].pdp_per_row = 1
rra[3].gamma = 1.0000000000e-01
rra[3].cdp_prep[0].deviation = NaN
rra[4].cf = "DEVPREDICT"
rra[4].rows = 1440
rra[4].cur_row = 1351
rra[4].pdp_per_row = 1
rra[5].cf = "FAILURES"
rra[5].rows = 288
rra[5].cur_row = 114
rra[5].pdp_per_row = 1
rra[5].delta_pos = 2.0000000000e+00
rra[5].delta_neg = 2.0000000000e+00
rra[5].failure_threshold = 7
rra[5].window_length = 9
rra[5].cdp_prep[0].history = "000000000"
注意HWPREDICT的rra-num参数是没加的,于是其他的RRAs将用缺省的参数隐式创建。
它的创建等同于:
rrdtool create monitor.rrd --step 300 \ DS:ifOutOctets:COUNTER:1800:0:4294967295 \ RRA:AVERAGE:0.5:1:2016 \ RRA:HWPREDICT:1440:0.1:0.0035:288:3 \ RRA:SEASONAL:288:0.1:2 \ RRA:DEVPREDICT:1440:5 \ RRA:DEVSEASONAL:288:0.1:2 \ RRA:FAILURES:288:7:9:5在这个例子中,预测算法基线适应迅速;事实上,最近期的一个小时的观察(每5分钟的间隔时间)占75 %的基准(baseline)预测。线性趋势(linear trend)预测适应更为缓慢。最后一天做的观测结果(每天288个观测结果)仅仅占了线性趋势(linear trend)的65%,请注意:这些计算依赖于一个指数平滑公式描述(在LISA 2000 paper中)
季节性的周期是一天(300秒中288个数据点)以及季节性的适应参数将被设置为0.1 。wrap around【见第一节术语中的说明】前,该rrd文件将存储5天( 1'440数据点)的预测和偏差的预测,该文件将存储一天(季节性周期) 0-1指标在FAILURES RRA中。
官方红色部分是错误的,例子中我已经修正
表达的内容很简单,就是将前2个DS源做下简单的运算,cdef的公式是"Duration,Total,0,EQ,1,Total,IF,/"
Info 看一下就知道了:
filename = "proxy.rrd"
rrd_version = "0003"
step = 300
last_update = 1219745286
ds[Total].type = "DERIVE"
ds[Total].minimal_heartbeat = 1800
ds[Total].min = 0.0000000000e+00
ds[Total].max = NaN
ds[Total].last_ds = "U"
ds[Total].value = 0.0000000000e+00
ds[Total].unknown_sec = 186
ds[Duration].type = "DERIVE"
ds[Duration].minimal_heartbeat = 1800
ds[Duration].min = 0.0000000000e+00
ds[Duration].max = NaN
ds[Duration].last_ds = "U"
ds[Duration].value = 0.0000000000e+00
ds[Duration].unknown_sec = 186
ds[AvgReqDur].type = "COMPUTE"
ds[AvgReqDur].cdef = "Duration,Total,0,EQ,1,Total,IF,/"
ds[AvgReqDur].last_ds = "U"
ds[AvgReqDur].value = 0.0000000000e+00
ds[AvgReqDur].unknown_sec = 186
rra[0].cf = "AVERAGE"
rra[0].rows = 2016
rra[0].cur_row = 747
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[0].cdp_prep[1].value = NaN
rra[0].cdp_prep[1].unknown_datapoints = 0
rra[0].cdp_prep[2].value = NaN
rra[0].cdp_prep[2].unknown_datapoints = 0
结尾语:如果对时间序列预测算法还不太了解的同学可以参阅《统计学原理》