<?xml version="1.0" encoding="UTF-8"?>
<rdf:RDF
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns="http://purl.org/rss/1.0/"
xmlns:dc="http://purl.org/dc/elements/1.1/">
<channel rdf:about="https://dwt.life/feed/rss/tag/RRD/">
<title>dwt&#039;s life - RRD</title>
<link>https://dwt.life/tag/RRD/</link>
<description></description>
<items>
<rdf:Seq>
<rdf:li resource="https://dwt.life/archives/15/"/>
<rdf:li resource="https://dwt.life/archives/13/"/>
</rdf:Seq>
</items>
</channel>
<item rdf:about="https://dwt.life/archives/15/">
<title>RRD浅析</title>
<link>https://dwt.life/archives/15/</link>
<dc:date>2021-06-30T13:48:00+08:00</dc:date>
<description>本文是对开源监控工具Ganglia使用的RRD数据库的一个简单介绍，此外还有一些有关RRDTool的基本操作。RRD数据库RRD是Round Robin Database的缩写，是一种环形数据库，它是专门设计来存储时序数据的。每当有新的数据到来时，一般也会有一个时间戳伴随着被存储起来，这里的时间戳是epoch值。RRDTool是RRD数据库配套的一个工具，它可以安装在Unix或者Windows系统上，RRDTool提供了一系列的命令集来对RRD进行不同的操作。RRD数据库与其他数据库的不同:RRDTool既是后端工具，又是前端工具；之所以这么说，是因为作为数据库，首先RRDTool可以存储数据，此外，RRDTool也提供了一个根据数据库数据进行绘图的功能，这让它具备了前端的特性。对于线性数据库，一般新的数据都被插入到数据库表的最后，所以数据库的大小随着数据的插入而不断的增长；而对于RRD数据库，其大小在创建时就已经指定。简单的说，可以把RRD数据库想象成一个环，数据都被插入到环的周边，有一个指针时钟指向新的数据要插入到的位置，当指针达到起始点时，就会覆盖原来存在的数据，这样一来，数据库的大小就固定不变了，这也是“Round Robin”的由来。其他数据库的数据都是被提供的，而RRD数据库可以通过配置，来计算旧的数据到新的数据之间的变化，并把这些信息存储起来。其他数据库更新的驱动是新的数据被提供，而RRD数据库的更新是按照按照预先定义的时间间隔来进行的；如果在固定的事件间隔内没有获得新的数据，那么RRDTool将会存储一个UNKNOWN值，所以一般使用RRD数据库都会有一个脚本每隔一段时间就向RRD提供一个数据。RRD的基本结构因为RRD数据库设计目的是监控，所以它的结构比较简单，创建一个RRD数据库的方式如下：rrdtool create target.rrd \     
         --start 1023654125 \     
         --step 300 \      
         DS:mem:GAUGE:600:0:671744 \     
         RRA:AVERAGE:0.5:12:24 \     
         RRA:AVERAGE:0.5:288:31下面是相关的一些基本概念：DS: Data Source, 它指的是设备上被监控的变量，一个RRD数据库中可能有多个DS。其声明格式如下：DS:variable_name:DST:heartbeat:min:max每隔一个step, DS的一个新的值就会到来，然后数据库就会被更新，这个值也被叫做 PDP(Primary Data Point)，PDP的范围由min,max来制定，如果在heartbeat时间内没有 收到数据，那么该PDP就会被置为UNKNOWN。在上面的例子中，每隔300s就会产生一个新的 PDP。DST: Data Source Type, 指的是DS的类型，可以是COUNTER, DERIVE, ABSOLUTE, GAUGE，详细解释如下表：CF: Consolidation Function, 是指合并数据的方式，可选的有AVERAGE, MAX, MIN, LAST。RRA: Round Robin Archive, 是对采集到的数据以某种方式(CF)的归档。声明格式如下RRA:CF:xff:step:rows在这里又有一个新的概念CDP(consolidated data point), 一个CPD是把step个PDP按照指定的CF进行合并得到的一个数值，而这个RRA中包含rows个CDPs。这里的xff是指CDP合并时允许出现的UNKNOWN的最大比率，在本例中即是，如果step个PDP中有一半是UNKNOWN，那么该CDP是UKNOWN,否则就去不是UKNOWN值的平均值。如下图是RRA的结构以及数据更新的方式：如图所示，在RRD数据库中会为一个RRA分配一部分空间，n(step)个sample(PDP)合并成一个CDP然后存储到这块区域的开头位置，如果空间已满则旧的数据会被覆盖，这样的方式就保证了数据库的大小是不会增长的，同时将PDP合并成CDP的做法，又可以保证RRD可以存储很长一段时间的数据。了解了这些基本概念之后，上面的这个例子就比较容易理解了,首先给这个数据库命名为target.rrd，数据的开始时间是epoch时间1023654125，每隔300s获取一个PDP，然后DS制定了实际被监控的变量及其类型和值域，最后定义了两个RRA，对于第一个RRA, 12(steps)个PDPs以平均(CF)的方式进行合并得到一个CDP，24个这样的CDP组成一个RRA归档。PDP之间的间隔是300s,所以CDP之间的间隔就是12*300，即1小时，24个这样的CDP就是1天，因此我们可以得知，第一个RRA就是mem的一天的监控统计。RRDTool常用命令rrdtool dumprrdtool dump filename.rrd [filename.xml] [–header|-h {none,xsd,dtd}] [–no-header|-n] [–daemon|-d address] [&gt; filename.xml]含义：将一个rrd数据库导出为xml文件示例：rrdtool dump load_one.rrd test.xmlrrdtool fetchrrdtool fetch filename CF [–resolution|-r resolution] [–start|-s start] [–end|-e end] [–align-start|-a] [–daemon|-d address]含义：从一个rrd数据库根据条件取出数据示例：rrdtool fetch load_one.rrd AVERAGE -r 12 -s e-1200 -e nowrrdtool xportrrdtool xport [-s|–start seconds] [-e|–end seconds] [-m|–maxrows rows] [–step value] [–json] [–enumds] [–daemon|-d address] [DEF:vname=rrd:ds-name:CF] [CDEF:vname=rpn-expression] [XPORT:vname[:legend]]含义：可以从若干个RRD中得到XML或JSON格式的数据。示例：rrdtool xport --start end-1h --end now --step 10 
DEF:ds1=load_one.rrd:sum:AVERAGE DEF:ds2=load_one.rrd:num:AVERAGE XPORT:ds1:sum XPORT:ds2:numrrdtool graphrrdtool graph|graphv filename [option …] [data definition …] [data calculation …] [variable definition …] [graph element …] [print element …]含义：根据RRD数据库中的数据绘制图形，生成图片。示例：rrdtool graph new.png --end now --start end-150 --title cpu_user --vertical-label % --width 250 --height 150 DEF:ds=cpu_user.rrd:sum:AVERAGE:step=3 AREA:ds#0000FF:cpu_user生成的图片：</description>
</item>
<item rdf:about="https://dwt.life/archives/13/">
<title>RRD 数据库简介及操作</title>
<link>https://dwt.life/archives/13/</link>
<dc:date>2021-06-30T13:35:00+08:00</dc:date>
<description>RRD 数据库简介及操作最近公司在部署了一套小米开源的监控平台 — open-falcon，有机会认识了 RRD(更多被称作 RRDTool)。好久没 blog 了，今天跟大家分享一下这个数据库。RRD 简介RRDtool refers to Round Robin Database tool.Round robin is a technique that works with a fixed amount of data, anda pointer to the current element.Think of a circle with some dots plotted on the edge. These dots arethe places where data can be stored.Draw an arrow from the center of the circle to one of the dots; thisis the pointer.When the current data is read or written, the pointer moves to thenext element.As we are on a circle there is neither a beginning nor an end, you cango on and on and on.After a while, all the available places will be used and the processautomatically reuses old locations.This way, the dataset will not grow in size and therefore requires nomaintenance.RRDtool works with Round Robin Databases (RRDs). It stores andretrieves data from them.以上摘自RRDTool 官网的表述。RRD 数据库是一个环形的数据库，你可以把它想象成表，中心处有一个指针，随着时间的变化，指针也在变，当指针指到 12 点处，也就是这个记录要被擦除覆盖的时候，所以它是大小固定的。总结起来，RRD 的关键词就是：环形、大小固定、无需运维、绘图时序数据库看完 RRD 的简介，尤其是它的关键词，是不觉得“我靠这么nb”。数据库按照功能和种类可以分成很多，各自术业有专攻，针对专门的领域进行数据存储。比如 mysql 的优势就是存储结构型数据，nosql 就是针对非结构型数据的。在运维领域里，需要不断的对服务器、交换机等支持性设备的性能和运行进行监控，这类监控的数据的特点就是跟着时间走 —— 它们的指标只会随着时间的变化而变化，不会涉及回头修改。这就区别于常见的数据库，会不断的修改历史数据，对数据进行 U（pdate） 操作。所以就应运而生了一系列数据库，名曰“时序数据库”。常见的时序数据库有：influxdb、opentsdb、rrd 等。其实如果你对 mysql 的引擎有足够了解的话，除了常见的 innodb 和 myisam ，还有一个引擎叫 archive ，它的作用和 rrd 差不多，支持插入和查询操作，比较专。RRD 的安装我的环境是 centos6.5 。安装的 rrdtool 版本是 1.4.7 ，源码安装。wget http://oss.oetiker.ch/rrdtool/pub/rrdtool-1.4.7.tar.gz
tar zxvf rrdtool-1.4.7.tar.gz
cd rrdtool-1.4.7
./configure --prefix=/usr/local
make
make install至此 rrdtool 的安装已经完成。读者要是缺啥依赖，请自行 google || baidu 解决。RRD 的操作下面介绍一下 RRD 数据库的操作，包括创建、增、查、绘：创建命令：rrdtool create filename \
               [--start|-b start time] \
               [--step|-s step] \
               [DS:ds-name:DST:heartbeat:min:max] \
               [RRA:CF:xff:steps:rows] \

               [--template|-t template-file] \
               [--source|-r source-file] \
               [--no-overwrite|-O] \
               [--daemon|-d address] 例子：rrdtool create test.rrd             \
            --start 1469341292       \
            DS:speed:COUNTER:600:U:U  \
            RRA:AVERAGE:0.5:1:24       \
            RRA:AVERAGE:0.5:6:10讲解：命令中，有用的基本上只有前五行，逐行解释。rrdtool create filename这个一看就很明白，就是通过 rrdtool 命令进行数据库创建，名为 filename 。例子里创建了一个名为 test.rrd 的数据库，其中 .rrd 为 rrd 数据库的后缀名。[--start|-b start time] 这句的意思是要指明该数据库的起始时间戳，例如例子中的 1469341292 是一个写此文的 unix timestamp 。你当然要指明起始时间了，因为这是时序数据库，肯定得有一个开始。[--step|-s step]这个 step 的意思是“你多久向数据库上报一次数据”，以秒为单位。例如例子中的，噢，例子里没有。。。。好吧，默认是 300s 一上报，也就是 5 分钟一上报，你可以按自己的需求上报。[DS:ds-name:DST:heartbeat:min:max]这个复杂些，我们拆开看。DS， DataSource，数据源，后面 ds-name 是需要你来指明的，比如，我给我们的数据源起个标示名为：speed。意思是，我这个数据库里面记录的都是关于 speed 的数据。DST， DataSourceType，数据源类型，DST 是你需要指明的。有几个选择，其中有 4 个是常用的，来说一下：COUNTER，GAUGEDERIVEABSOLUTE举例说明他们之间的不同：我在 10:30 和 10:31 分别插入了两个数据：10:30 60010:31 1200那么如果你的 DST 是COUNTER，(1200-600)/step = 600/300 = 2，这个结果 2 就是最后要往数据库里插入的数据，并且是 10:31 时刻的数值。GAUGE，10:30 的值是600,10:31 的值是1200 。都是原值存储，这个是最常用的。DERIVE，他的原理跟 COUNTER 一样，不同的是 COUNTER 只能递增，但是 DERIVE 可增可减。比如，对于 COUNTER ，10:30 是 600 ， 10:31 是 1200 ， 那么 10:32 的值必须大于 1200 ；但是 DERIVE 在 10:32 的值可以是小于 1200 的。ABSOLUTE，这个是直接做均值，600/step = 1 , 1200/step = 2， 所以 10:30 的值是 1 ， 10:31 的值是 2 。heartbeat ， 心跳。心跳的意思，我自己经过实践和文档，总结出来心跳是跟 step 配合使用的。还是举例：比如，我的 step 是 60s 上报一次数据如果我的 heartbeat 是 60s ，那么 10:30 600， 10:31 没上报， 10:32 1200，这时候，图像就会在 10：31 处没有记录，也就是图像断开了；如果我的 heartbeat 是 120s，那么 10:31 也会有数据，图象是不会中断的。但是，是以什么样的值来填充，是有条件的，后面说明。其实说白了，这个 heartbeat 就是一个容错时间，如果在这个时间间隔内没有上传数据，那么我就不能给你绘图。min，能接受的最小值，比如上报的数据不能小于 500 ，那你就设置这里。max，同理。一般这两个值都是U，表示无限。[RRA:CF:xff:steps:rows]这个意思是创建数据表，刚才创建的是数据库，现在创建数据表。RRA：Round Robin ArchiveCF： Consolidation Function，合成函数、合成方法。rrd 提供的 CF 有下面这么几种：Average()Max()Min()Last()这个函数是做什么的？先继续看后面的参数。xff，这是一个小于 1 的比例值，表示正常值与异常值的比值，相当于数据的合格率，如果低于这个比例，那么该数据就算废弃。一般设置成 0.5。steps，这个参数的意思是，多少个值通过 CF 函数合成一个值，并存入数据表。rows，表示你这个环形的数据库有多少个格子，也就是说你这个数据表能存多少数据。好了，合起来讲解一下这个 RRA 的命令参数。还是举例子吧，不太好解释，举例：timePDP10:301.410:312.810:323.710:334.210:345.110:356.6RRA:CF :xff:steps:rowsRRA:AVERAGE:0.5:1 :24 — ①RRA:AVERAGE:0.5:6 :10 — ②如果按①来说，意思是，我这个数据表能存 24 个值，steps 是 1 ，意思是我每上报一个值就算一个存储值。这样的话， 10:30 到 10:35 上报的什么值，就存什么值：time上报存储10:301.41.410:312.82.810:323.73.710:334.24.210:345.15.110:356.66.6如果按②来说，意思是，我这个数据表能存10个值，steps 是 6，意思是我每上报 6 个值，求 Average() ，把结果存到数据表里：time上报存储10:301.4 10:312.8 10:323.7 10:334.2 10:345.1 10:356.6(1.4+2.8+3.7+4.2+5.1+6.6)/6 = 3.96为什么会有多个 RRA ，采样，采不同时间段的样，然后当你画图的时候，给你提供最适合你要求的时间段的数据给你。增命令：rrdtool {update | updatev} filename [--template|-t ds-name[:ds-name]...] [--skip-past-updates|-s] [--daemon|-d address] [--] N:value[:value]... timestamp:value[:value]... at-timestamp@value[:value]...例子：rrdtool update test.rrd \
           1469341292:12420 \
           1469341352:12422 \
           1469341412:12423或rrdtool updatev test.rrd \
           1469341292:12420 \
           1469341352:12422 \
           1469341412:12423update 和 updatev 的区别就是多了一个 v ，罗嗦、详情。没错就是这么简单。查命令：rrdtool fetch filename CF [--resolution|-r resolution] [--start|-s start] [--end|-e end] [--align-start|-a] [--daemon|-d address]例子：rrdtool fetch test.rrd AVERAGE --start 1469341292查看数据库结构的命令：rrdtool info filename [--daemon|-d address [--noflush|-F]]例子：rrdtool info test.rrd绘图rrd 的主要功能分为两块，一个就是存储数据，一个就是根据数据绘图。命令：rrdtool graph|graphv filename [option ...] [data definition ...] [data calculation ...] [variable definition ...] [graph element ...] [print element ...]例子：rrdtool graph test.png  \
         --start 1469341292 --end 1469341412 \
         DEF:myspeed=test.rrd:speed:AVERAGE \
         LINE2:myspeed#FF0000
这里就解释一下 DEF ：DEF:myspeed=test.rrd:speed:AVERAGE定义了一个 myspeed 的图，其内容来源来自于 test.rrd ， DS 名为 speed ， CF 是 AVERAGE。python 操作通过 pip 安装 rrdtool 模块，该模块可以通过 python 进行 RRD 数据库的创建、绘图等操作。pip install rrdtool所有的操作代码：import rrdtool

rrdtool.create(&#039;test.rrd&#039;, &#039;--start&#039;, &#039;1469341292&#039;,
&#039;--step&#039;,&#039;60&#039;,&#039;RRA:AVERAGE:0.5:1:3&#039;, &#039;DS:test:GAUGE:120:U:U&#039;)

rrdtool.update(&#039;test.rrd&#039;,&#039;1469341292:300&#039;)
rrdtool.update(&#039;test.rrd&#039;,&#039;1469341352:600&#039;)
rrdtool.update(&#039;test.rrd&#039;,&#039;1469341412:900&#039;)
rrdtool.update(&#039;test.rrd&#039;,&#039;1469341472:1200&#039;)

rrdtool.graph(&#039;test.png&#039;,&#039;--start&#039;,&#039;1469341292&#039;, &#039;--end&#039;,&#039;1469341472&#039;,&#039;DEF:myspeed=test.rrd:test:AVERAGE&#039;,&#039;LINE2:myspeed#FF0000&#039; )更过的绘图方法，可以参看这里总结RRD 蛮好用。不用怎么操心，属于一劳永逸的数据库。理解起来比较费劲的是创建时候的 DS 那部分和 RRA 的参数那块。多动手操作，边实践边看本文效果更好。</description>
</item>
</rdf:RDF>