Chinaunix首页 | 论坛 | 博客
  • 博客访问: 139256
  • 博文数量: 19
  • 博客积分: 1416
  • 博客等级: 上尉
  • 技术积分: 273
  • 用 户 组: 普通用户
  • 注册时间: 2008-12-22 00:49
文章分类

全部博文(19)

文章存档

2010年(4)

2009年(15)

我的朋友

分类: LINUX

2010-05-12 23:42:17

不知道从什么时候开始,rrdtool里带了rrdcached这个程序,准备试用一下。官网已经有了比较详细的介绍,但是都是英文,翻译一个先。
原文网址:

当rrdcached接收到update的命令的时候,它并不会把这个命令写入磁盘,它会在多个队列中,寻找相应rrd文件的队列,如果没有的话,会创建一个队列,并且把自己,和当前的时间戳插进去。注意:当前的时间戳并不是update命令中带的那个时间戳哦,这个当前的时间戳,就有了特殊的含义,在判断是否刷新磁盘的时候会用到,我们把它叫做First。此时,这条update命令的时间戳(Time)和值(Value),已经添加成为了队列树的节点。

当下一个节点要进入队列的时候,它会先检查,这个队列是不是需要把队列中的数据flush到rrd文件中了,当 现在的时间戳 - First >= Timeout 的时候,它就会触发flush操作,注意,是触发,而不是直接写rrd,这个问题随后解释。这个Timeout,是在启动rrdcached的时候,用-w参数指定的,默认为5分钟。
所谓的触发flush操作,并不是直接写rrd文件,而是把这个队列移动到一个update queue中,当下一次写rrd的线程被触发的时候,这些在update queue中的值,就会被真正的写到磁盘中。

我们会起多个update的线程,来进行rrd的写操作。每个线程都会取出update queue中的第一个值,并且将它写入磁盘的rrd文件中,这种方式十分高效,当update queue非空的时候,rrd文件会在最短的时间内被写入。

我们可能都发现了一个问题————只有队列接到update命令的时候,进程才会检测,这个队列是不是需要被flush到rrd中了,有一种场景:如果一个rrd文件,有了一次update之后,很久很久都没有更新了,那队列中就一直有这么一个值,而无法被写入到rrd中,这个现象,显然不是我们希望看到的……所以,我们每隔一段时间,所有的缓存队列中的值,都会一起被flush到update queue中,等待被更新到rrd文件中。这个操作,一般来讲,是非常消耗资源的,所以,不应该经常的做这种事情,这个间隔应该调的大一点,是由-f参数指定的,默认是一个小时一次。

rrdtool给这种cache提供了一个flush的命令,我们可以针对特定的rrd文件进行flush,当rrdcached接到这个命令的时候,它会先找到这个rrd文件的队列,并且将这个队列添加到update queue的顶端,当这些数据全部被写rrd的线程写到磁盘中以后,这个命令才会返回。

1、文件的队列以平衡树的方式存储
2、平衡树中的节点,和update queue的节点是一个struct
3、First和update命令中带的时间,可能会不一样
4、触发update的那个节点,被添加到队列尾部
5、flush命令,会将值插到update queue的头部
6、ascII编码通讯

官方文档还提到了以下的几点:
1、用户认证:暂时没有
2、授权:对每个socket进行授权,就是,每个socket可以接受的命令是不同的
3、加密:没有加密
4、检查:没有,你让它写哪个文件,它就写哪个文件,如果你用root起了这个进程,而它给一个很敏感的文件写了些东西,把你写死了……你就挂了
协议
它的协议很简单,没有经过任何认证和加密,很容易用脚本实现,也可以直接telnet上来敲命令。⊙﹏⊙b汗……
命令是基于行的,一个命令就是一行或者多行,行和行之间用'\n'分隔。

命令格式:
都很简单,有个HELP命令,可以看到详细的帮助。
有两个命令需要注意下:
BATCH
在执行了BATCH以后,你可以插入多行,这个时候,rrdcached会执行update的操作,但是并不会有返回,只有client端输入一个结束标志:'.'的时候,rrdcached才会返回,你执行了多少命令,错了多少行,哪行错了,是哪些错……
STATS
输出rrdcached运行到现在的状态,监控用。
QueueLength:有多少节点在update queue中等待写入rrd
UpdatesReceived:总共接受了多少update命令
FlushesReceived:总共接受了多少flush命令
UpdatesWritten:总共update的次数
DataSetsWritten:总共有多少Data set被写入了磁盘
TreeNodesNumber:在平衡树中有多少节点
TreeDepth:平衡树的深度
JonunalBytes:总共写了多少Byte到journal
JournalRotate:journal总共滚动了几次

翻译至此结束……如果觉得意犹未尽,请直接看官网的文档,如果还觉得不爽,请直接看源码……

rrdtool还是个不错的东东,但是有两个磁盘写上的问题很麻烦:
1、当rrd文件非常多的时候,而且都是监控数据,5分钟就需要全部更新,更新的时候,光寻道都寻死了,而且如果内存无法全部cache,每次更新,都会造成大量内存和硬盘之间的数据交换……非常耗资源
2、每次update,都先打开一个file handler,然后更新一条,然后关闭file handler,当更新下一条的时候,继续这么搞……很耗资源

第一个问题,通过mysql来解决,数据库中以时间戳做pk,监控数据先插数据库,这样,在数据库中做insert delay,因为mysql中的数据按照pk进行聚合,所以,就成为了批量顺序写入,而且mysql自己会保持文件句柄。
当需要绘图的时候,先向数据库发送请求,取出要插入这个rrd的数据,然后update,然后绘图,这样虽然多了一个步骤,但是,在update的时候,这个绘图的rrd文件可以保证都cache在内存中,也可以一次性被flush到硬盘,以此来提高写入rrd的速度。当批量更新rrd的时候,内存和硬盘只需要交互一次,就更新了全部的数据,而原先,交互一次才更新一条……

但是,这个方法,还是无法解决update的时候频繁打开file handler的问题,有了rrdcached以后,这个问题貌似被解决了,在批量更新一个rrd的时候,我可以先将数据都准备好,然后再一个BATCH命令中,一次性更新上去,然后对此文件进行FLUSH操作,如果只需要打开一次文件句柄,就完成了所有数据的更新,那就最好了,但是,这种批量更新,是否真的是只打开一个文件句柄,还需要看源码了……
阅读(4717) | 评论(0) | 转发(0) |
0

上一篇:使用RRD的一个教训

下一篇:没有了

给主人留下些什么吧!~~