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 文件的权限)