cacti我们也用了很久了,但是它的表结构一直都没有去关心过,得空抽了半个晚上的时间,把它的库表结构大概看了下,某些字段的含义跟大家分享下:
cacti的数据都是存放在rrdtool中的,数据库存放的其实只是配置数据,cacti的逻辑对象主要分为三种,data(数据)、graph(图片)、host(设备),这在它的表设计中也能很容易的看出来。所以,就分三个大类来讨论了。
一、Host
cacti的host一般是要使用模板的,每个host自己的信息,只存放在host表中,其余的就都是模板的信息,模板的对应关系等等。
1、host表
host表有34个字段,用来存放设备信息,就是我们在console的devices选项中可以看到,并且配置的东东。具体字段的含义如下:
id:就是设备的id,自增
host_template_id:如果这个设备使用了模板,那这个就是模板的id
description:描述,在cacti里看到的设备名
hostname:设备ip地址
notes:不做解释
snmp_community、snmp_version、snmp*......:snmp相关的配置选项,就是字面的意思
availability_method:在页面上看就是Downed Device Detection,我理解就是,如何看这台设备是否挂了
ping_method:udp ping还是icmp,还是tcp
ping*......:ping的相关选项,字面意思
max_oids:一次最多get多少个oid
status*......:设备当前状态相关,字面意思
一堆time:不太清楚,应该是pollor相关的,具体单位不知
total_polls:总共取了多少次值了
failed_polls:失败了多少次
availability:可用性,上面两个字段算出来的
2、host_template表
设备模板,总共就三个字段,第一个是id,就是host_template_id,在host表里有引用,第二个是个哈希,就是模板的位置索引,第三个是索引名字。
3、host_template_graph表
模板的对应,存放的信息主要是,一个设备模板,需要绘什么图,也就是设备模板和绘图模板的对应关系,就两个字段,host_template_id和graph_template_id,graph_template_id就是graph_templates里面的id值。
4、host_template_snmp_query表
模板和数据抓取方式的对应,对应的数据抓取方式就是snmp_query_id,在snmp_query表的id值。
每个snmp_query,都会对应有graph,如果一个设备模板,对应了一个snmp_query,这个snmp_query又对应了一系列的graph,那这个设备模板就自动对应这些graph,而这个关系在host_template_graph里是没有的
5、host_graph表
设备和图片模板的对应,也是两个id,host_id和graph_template_id,graph_template_id在graph_templates表中定义。
一般来讲,这个设备下的图片,会包含它所属的设备模板和图片模板的对应,也就是说,这个对应关系,和host_template_graph表中有些类似。
6、host_snmp_cache表
存放snmp去取值时的临时值,例如网络流量,需要的是累加值,那这里就存上次的总值,用来计算用
7、host_snmp_query表
设备和snmp_query的对应,和host_graph类似,这个对应关系,和host_template_snmp_query表中的数据是对应的。
二、Data
data主要就是数据获取,获取数据,然后存放到rrd文件中,这里存放的数据,主要就是如何获取数据、和如何存放数据这两种。
1、data_input表
数据获取的方式,在console中的data_input_method里可以看到。
id:数据获取方式的id
hash:对应的磁盘索引
name:数据获取方式的名字
input_string:如果是脚本的话,那就是脚本的位置了
type_id:type一直没找到对应的表,可能是程序里写死了,对应的是input_type,有6个选项,分别是:snmp、snmp query、script/command、script query、script – script server、script query – script server
2、data_input_fields表
这张表是用来存放一些data_input方法中所需要的对象,比如snmp的oid,那就是一个对象,script方式取硬盘时候,取回来值的名字,单位,都属于它所定义的范畴。表内容,主要是这些对象,和data_input的对应。
id:input_fields的id
data_input_id:对应data_input表中的id
name、data_name:名字
input_output:输入还是输出
下面几个字段我也不清楚了……
3、data_input_data表
存放的是每个data对象的data_input_field内容。
data_input_field_id:data_input_field中的id
data_template_data_id:data_template_data中的id
4、data_local表
存放数据对象,就是在console中的data source页面看到的东东。不过这张表只是简单的定义一个对象和对应关系,对象的具体属性在另外的表中。
id:data的id
data_template_id:采用了哪个数据模板,在data_templates模板中定义
host_id:是哪个设备的数据,在host中定义
snmp_query_id:如果是通过snmp_query方式获取的,那对应的snmp_query的id,如果不是,则为0
snmp_index:snmp_query方式获取数据时,获取数组的前缀。例如,流量获取中,端口的index
5、data_template表
数据模板,我们在console的data templates中看到的东东。
id:数据模板的id
hash:索引
name:名字
6、data_template_data表
具体数据对象的信息,包含模板。可以认为,每一个对象都代表一个rrd文件。
id:data对象的id
local_data_template_data_id:如果使用了模板,那这个就是模板的id,定义的位置也是这个表
local_data_id:对应的数据对象,在data_local表中定义
data_template_id:data_template,数据模板,在data_template表中定义。
data_input_id:数据获取的方式,在data_input表中定义
*name:名字,就是字面的意思
data_source_path:rrd文件的路径
t_*:不知道……
active:是否被激活,可以通过enable/disable来控制
rrd_step:步长,默认是300s,就是5分钟,也就是多长时间存一个数据(rrdcreate的选项)
7、data_template_data_rra表
数据对象和rra的对应,rra也是rrdtool中的概念,是一种数据归档压缩的机制。
data_template_data_id:上张表中定义的id
rra_id:对应的rra的id,在rra表中定义
8、data_template_rrd表
基本上也是rrdtool的配置选项,一个rrd文件可以存多列,叫做ds,每个列代表一组数据。这张表可以看成是对这个列的定义。
id:ds的id
local_data_template_rrd_id:如果使用了ds的模板,则这里定义模板的id,模板定义也在这张表中
local_data_id:数据id,在data_local表中定义
data_template_id:采用的数据模板,在data_template_data中定义
其余的都是rrdtool在创建rrd文件时候,对这个ds的配置选项,例如最大值,名字等等。
data部分还是比较复杂的,如果和host连起来看,就更复杂了。抛开模板不谈,一般来讲是有以下的对应关系:
1、每个host_id,都有一组local_data_id,例如,一个cisco交换机的cpu就是一个local_data_id,它的一个端口——te1/1流量,也是一个local_data_id。一个host_id对应多个local_data_id。
2、每个local_data_id,就是一个数据源,它必须有一个rrd文件与他对应,所以每个local_data_id在data_template_data中,必定对应一行记录,必定有一个rrd文件。别看data_template_data中有那么多记录,其中local_data_id为0的,或者rrd路径为空的,那都是模板。
3、每个rrd文件,必然至少有一个ds,也就是在data_template_rrd中,至少有一条记录,例如流量,还是cisco的交换机,每个端口代表一个local_data_id,有一个rrd文件,有两个ds,流入和流出,那在data_template_rrd中就有两条记录。
4、data_input那几张表,主要是数据获取方式,数据获取方式有6种,我们一般用的是三种:脚本直接取,就是script、snmp,给个oid直接get、snmp query,就是snmp取回来一组数据,然后分组。
三、Graph
绘图方面,自定义的方法其实很多,cacti并没有把rrdtool在绘图方面的参数全部表现出来,不过也已经够用了。
1、graph_local表
本地的图片,和data_local类似,一般来讲,一个data_local的对象,都会对应一个graph_local的对象,意思就是,一个数据,对应一张图片,但是也有可能出现不对应的情况,那就是:我有些数据并不绘图、或者有些图我需要多个数据。
表结构和data_local类似,不过data_template_id换成了graph_template_id,第一个id字段代表的含义也变了,代表graph对象。
2、graph_templates表
绘图模板。
id:模板的id
hash:索引
name:名称
3、graph_template_input表
graph_template对应的具体对象类型,比如说这个类型是个颜色,这个类型是流量数据流入的数据源,等等。
id:数据类型的id
hash:索引
graph_template_id:图片模型的id,在graph_template中定义
name:名字
description:不作说明了
column_name:对象的类型,是颜色,还是数据源,还是一段文字
4、graph_template_input_defs表
定义图中的具体对象类型和item的对应。
graph_template_input_id:graph_template_input的id,类型是什么
graph_template_item_id:具体对象的id,在graph_templates_item中定义
5、graph_templates_gprint表
输出格式
6、graph_templates_graph表
绘图时候的选项,每张图在这张表中对应一条记录,大多是rrdtool的参数。和data_template_data类似。
id:绘图选项的id
local_graph_template_graph_id:如果采用模板的话,这里就是模板的id。模板中定义好的东西,就不用重新定义了。在本张表中有定义
local_graph_id:是哪张图,在graph_local中定义
graph_template_id:在graph_templates表中定义的绘图模板
剩下的都是rrd绘图的选项了,例如绘的图有多高,多宽,图片的名字是啥等等......
7、graph_templates_item表
每张图上,对应的有些什么内容。内容主要是包含:线或者是面,就是趋势图、下面的标注,例如最大值,最小值,当前值。
id:item的id
hash:
local_graph_template_item_id:如果采用了模板,则写模板的id,在本表中定义
local_graph_id:对象属于哪张图
graph_template_id:在graph_templates表中定义的绘图模板
task_item_id:如果对象的类型是task_item_id(在graph_template_input中定义),则这里的id就是数据源的id,在data_template_rrd中定义。
color_id:颜色,在color表中定义
alpha:透明度
graph_type_id:图的类型?
cdef_id:如果这个值是计算出来的(例如多个值的累加),那这里要有计算的公式,在cdef表中定义
consolidation_function_id:功能函数,比如取平均值,取最大值等
text_format:字符串,直接显示在图上的东东,可以理解为对象的名字
value:值
hard_return:不知
gprint_id:输出格式
sequence:rrd的绘图是有顺序的,sequence大的对象会覆盖sequence小的对象
绘图的地方,是最复杂的地方,因为rrdtool本身在绘图的时候参数就是最多的,也是最复杂的,把这些东西都封装到数据库中,那这些表结构也是十分复杂的。一般情况下,可以这么理解:
1、每个host_id的对象,可以对应多张图,但是也有可能有某些图并不对应任何host,例如汇总的图。但是每张图必然在graph_local中有定义,就是有一个local_graph_id。
2、每张图片,在创建的时候肯定有很多参数,这些参数就是在graph_template_graph中定义的。如果采用了模板,那模板中定义过的参数,就不用再重复定义了。
3、每张图片,必然包含一个以上的对象,那就是graph_template_item了,item有很多类型,例如,流量图中,绿色区域代表的流出、蓝色实线代表的流出,就分别代表一个对象。还有些对象,例如下标的最大值,平均值等。这些对象,都是需要有数据源的,可能一个数据源,也可能需要多个,因为实际绘出来的值,是cdef把不同的数据源运算后得到的。这个数据源,就是ds,也就是data_template_rrd中的对象。
四、Cacti如何实现被动数据获取
了解到它的数据结构以后,我们就可以想办法来实现cacti数据的被动获取了,因为并不是所有场合,snmp都可以取到数据的,也许有时候我们要取的ip在另外一个局域网里,也许我们觉得cacti的负载太高,不能让它取太多的数据。
1、方式
方式很简单,在cacti中定义好host,data,graph,然后只要我们能定时的把数据插入到它的rrd文件中就可以了。
2、方法
方法可以有两种:
第一种用脚本,cacti支持自写脚本取数据。最土的办法,就是定时的将数据推送到cacti的机器上,追加到一个文件里,然后cacti通过一个脚本读取这个文件来获取数据。
第二种就是直接插rrd文件,cacti正常的获取数据方式是用crontab跑poller,或者spine,去定时取数据。我们在poller或者spine的过程中不需要让它去取数据,直接跳过,而定时的从外部把数据推送进来,然后插入rrd文件即可。
3、步骤
a、添加一个host(如果这个host无法访问到,那么可用性检查会失败,但是没关系)
b、添加数据源,需要insert以下几张表:data_local、data_template_data、data_template_data_rra、data_template_rrd
c、创建rrd文件,打开data source页面,应该已经可以看到我们添加的数据源了,打开那个数据源的debug模式,将rrdtool的命令拷贝到shell中执行一次即可(注意权限)
d、创建一个图片,需要insert以下几张表:graph_local、graph_template_graph、graph_template_item
e、定时的向rrd文件中插入数据(用你喜欢的方式,同时要注意rrd文件的权限)