ndo+mysql用的人还是挺多的,当监控节点多的时候,mysql经常先成为瓶颈,一旦它挂在那里,那整个nagios会因为等待ndo2db返回结果而挂住。所以,如果有必要的话,还是要对它进行一些优化。
一、是ndomod配置的优化
ndo
把乱七八糟很多没用的数据都入库了,很多东西其实我们并不需要,所以需要在源头上做一个筛选,在平时我只留了4个内容,nagios_servicechecks,nagios_hostchecks,nagios_servicestatus,nagios_hoststatus,
后两个是centreon用来展示用的,前两个是用来查历史检查记录用的。
如果需要记log的话,那也可以记log,不过ndo本身的log入库不是很喜欢,信息很不全,也不好查,所以log的入库建议单独搞。
选择ndomod的入库内容,是在ndomod.cfg里的一个叫data_processing_options的配置项,这个配置项默认是-1,那就是所有东西都入,如果想做一些筛选,那就需要到源码里查看,文件是include/ndomod.h
#define NDOMOD_PROCESS_PROCESS_DATA 1
#define NDOMOD_PROCESS_TIMED_EVENT_DATA 2
#define NDOMOD_PROCESS_LOG_DATA 4
#define NDOMOD_PROCESS_SYSTEM_COMMAND_DATA 8
#define NDOMOD_PROCESS_EVENT_HANDLER_DATA 16
#define NDOMOD_PROCESS_NOTIFICATION_DATA 32
#define NDOMOD_PROCESS_SERVICE_CHECK_DATA 64
#define NDOMOD_PROCESS_HOST_CHECK_DATA 128
#define NDOMOD_PROCESS_COMMENT_DATA 256
#define NDOMOD_PROCESS_DOWNTIME_DATA 512
#define NDOMOD_PROCESS_FLAPPING_DATA 1024
#define NDOMOD_PROCESS_PROGRAM_STATUS_DATA 2048
#define NDOMOD_PROCESS_HOST_STATUS_DATA 4096
#define NDOMOD_PROCESS_SERVICE_STATUS_DATA 8192
#define NDOMOD_PROCESS_ADAPTIVE_PROGRAM_DATA 16384
#define NDOMOD_PROCESS_ADAPTIVE_HOST_DATA 32768
#define NDOMOD_PROCESS_ADAPTIVE_SERVICE_DATA 65536
#define NDOMOD_PROCESS_EXTERNAL_COMMAND_DATA 131072
#define NDOMOD_PROCESS_OBJECT_CONFIG_DATA 262144
#define NDOMOD_PROCESS_MAIN_CONFIG_DATA 524288
#define NDOMOD_PROCESS_AGGREGATED_STATUS_DATA 1048576
#define NDOMOD_PROCESS_RETENTION_DATA 2097152
#define NDOMOD_PROCESS_ACKNOWLEDGEMENT_DATA 4194304
#define NDOMOD_PROCESS_STATECHANGE_DATA 8388608
#define NDOMOD_PROCESS_CONTACT_STATUS_DATA 16777216
#define NDOMOD_PROCESS_ADAPTIVE_CONTACT_DATA 33554432
可以选择自己需要的入库信息,然后把自己所选择的行右边的数字加起来,写到配置文件里去。
我选择的是如下几项
#define NDOMOD_PROCESS_SERVICE_CHECK_DATA 64
#define NDOMOD_PROCESS_HOST_CHECK_DATA 128
#define NDOMOD_PROCESS_PROGRAM_STATUS_DATA 2048
#define NDOMOD_PROCESS_HOST_STATUS_DATA 4096
#define NDOMOD_PROCESS_SERVICE_STATUS_DATA 8192
#define NDOMOD_PROCESS_OBJECT_CONFIG_DATA 262144
#define NDOMOD_PROCESS_MAIN_CONFIG_DATA 524288
#define NDOMOD_PROCESS_STATECHANGE_DATA 8388608
加起来的结果是data_processing_options = 9189568
这样一来,通过mysql的监控我发现,我的insert的数量减少了一半左右,从80 insert/s降到40 insert/s
二、mysql的优化
1、因为nagios_servicechecks和nagios_hostchecks这两个表基本上是插入,而且select也比较少,所以考虑把它切换成myisam的引擎,这样可以带来更快的插入速度。
alter table nagios_servicechecks engine=myisam;
alter table nagios_hostchecks engine=myisam;
nagios_servicestatus和hoststatus表因为更新比较快,所以用innodb
2、我把nagios全加上以后,就发现基本上没什么延迟了,但是过了两天,就出现了问题,检查后发现了有大量慢sql语句,这些慢sql语句居然都是delete语句。
原来,是ndo2db在删除过期的数据,但是我的表太大了,每次删除都要全表扫描,所以会很慢,insert语句得不到锁,就一直挂着,nagios等不到ndo返回结果,也一直挂着。
当时考虑的办法是加索引,delete语句加的条件是instance_id和start_time,所以直接对这两个做索引
create index ind_nagios_sc_ins_stime on nagios_serviceschecks(instance_id,start_time);
create index ind_nagios_hc_ins_stime on nagios_hostchecks(instance_id,start_time);
3、装好了centreon以后,在量很大的时候,有些表也是需要加索引的,这个看实际情况而定了
4、进一步的优化
三个方案:
a、
如果发现插入太多,mysql顶不住了,那可以考虑把insert换成insert
delayed,具体要修改的源码在src/dbhandlers.c中,函数是ndo2db_handle_servicecheckdata和
ndo2db_handle_hostcheckdata。
b、servicechecks和hostchecks表因为是myisam的引擎,
所以时间长了文件会越来越大,插入也会越来越慢;而且我的servicechecks数据保存一周,竟然有3000w条还多,查询起来也不方便,所以考虑
用merge引擎替换,把它分为7张表,分别命名为nagios_servicechecks_1到nagios_servicechecks_7,代表
周一到周日,前端做merge,然后每天插一张表,每天凌晨,就把自己今天要插的相应的表truncate掉,然后把merge表alter一下,改变下
顺序即可。
CREATE TABLE `nagios_servicechecks` (
`servicecheck_id` int(11) NOT NULL AUTO_INCREMENT,
`instance_id` smallint(6) NOT NULL DEFAULT '0',
`service_object_id` int(11) NOT NULL DEFAULT '0',
`check_type` smallint(6) NOT NULL DEFAULT '0',
`current_check_attempt` smallint(6) NOT NULL DEFAULT '0',
`max_check_attempts` smallint(6) NOT NULL DEFAULT '0',
`state` smallint(6) NOT NULL DEFAULT '0',
`state_type` smallint(6) NOT NULL DEFAULT '0',
`start_time` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`start_time_usec` int(11) NOT NULL DEFAULT '0',
`end_time` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`end_time_usec` int(11) NOT NULL DEFAULT '0',
`command_object_id` int(11) NOT NULL DEFAULT '0',
`command_args` varchar(255) NOT NULL DEFAULT '',
`command_line` varchar(255) NOT NULL DEFAULT '',
`timeout` smallint(6) NOT NULL DEFAULT '0',
`early_timeout` smallint(6) NOT NULL DEFAULT '0',
`execution_time` double NOT NULL DEFAULT '0',
`latency` double NOT NULL DEFAULT '0',
`return_code` smallint(6) NOT NULL DEFAULT '0',
`output` varchar(255) NOT NULL DEFAULT '',
`perfdata` varchar(255) NOT NULL DEFAULT '',
PRIMARY KEY (`servicecheck_id`),
UNIQUE KEY `instance_id` (`instance_id`,`service_object_id`,`start_time`,`start_time_usec`),
KEY `idx_serche_ins_start` (`instance_id`,`start_time`)
)
ENGINE=MRG_MyISAM DEFAULT CHARSET=gbk INSERT_METHOD=LAST
UNION=(`nagios_servicechecks_2`,`nagios_servicechecks_1`,`nagios_servicechecks_7`,`nagios_servicechecks_6`,`nagios_servicechecks_5`,`nagios_servicechecks_4`,`nagios_servicechecks_3`)
COMMENT='Historical service checks'
CREATE TABLE `nagios_hostchecks` (
`hostcheck_id` int(11) NOT NULL AUTO_INCREMENT,
`instance_id` smallint(6) NOT NULL DEFAULT '0',
`host_object_id` int(11) NOT NULL DEFAULT '0',
`check_type` smallint(6) NOT NULL DEFAULT '0',
`is_raw_check` smallint(6) NOT NULL DEFAULT '0',
`current_check_attempt` smallint(6) NOT NULL DEFAULT '0',
`max_check_attempts` smallint(6) NOT NULL DEFAULT '0',
`state` smallint(6) NOT NULL DEFAULT '0',
`state_type` smallint(6) NOT NULL DEFAULT '0',
`start_time` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`start_time_usec` int(11) NOT NULL DEFAULT '0',
`end_time` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`end_time_usec` int(11) NOT NULL DEFAULT '0',
`command_object_id` int(11) NOT NULL DEFAULT '0',
`command_args` varchar(255) NOT NULL DEFAULT '',
`command_line` varchar(255) NOT NULL DEFAULT '',
`timeout` smallint(6) NOT NULL DEFAULT '0',
`early_timeout` smallint(6) NOT NULL DEFAULT '0',
`execution_time` double NOT NULL DEFAULT '0',
`latency` double NOT NULL DEFAULT '0',
`return_code` smallint(6) NOT NULL DEFAULT '0',
`output` varchar(255) NOT NULL DEFAULT '',
`perfdata` varchar(255) NOT NULL DEFAULT '',
PRIMARY KEY (`hostcheck_id`),
UNIQUE KEY `instance_id` (`instance_id`,`host_object_id`,`start_time`,`start_time_usec`),
KEY `idx_hostche__ins_start` (`instance_id`,`start_time`)
)
ENGINE=MRG_MyISAM DEFAULT CHARSET=gbk INSERT_METHOD=LAST
UNION=(`nagios_hostchecks_2`,`nagios_hostchecks_1`,`nagios_hostchecks_7`,`nagios_hostchecks_6`,`nagios_hostchecks_5`,`nagios_hostchecks_4`,`nagios_hostchecks_3`)
COMMENT='Historical host checks'
每天凌晨执行的sql为
flush tables;
truncate table nagios_servicechecks_2; // nagios_servicechecks_2为当天要插的表
truncate table nagios_hostchecks_2;
alter table union = (......,`nagios_servicechecks_2`);
alter table union = (.........,`nagios_hostchecks_2`); // 把当天要插的表放到最后
这个可以放到crontab里用脚本实现。
这样的话,就用不着delete了,省下大批锁
做法是在源码中把delete的函数注释掉,源码在src/ndo2db.c中,具体位置在函数ndo2db_end_input_data的最后
把ndo2db_db_perform_maintenance(idi);这个函数的调用注释掉即可。
把这个去掉以后,相比以前性能还是提升了不少
+-----------------------+-----------+
| Variable_name | Value |
+-----------------------+-----------+
| Table_locks_immediate | 130032279 |
| Table_locks_waited | 112021 |
+-----------------------+-----------+
现在我的ndo库每秒300左右的insert,在删掉delete语句之前,从锁上来看,两个数字相差两个数量级,现在相差了3个数量级,说明还是有点作用的,呵呵。
c、两个status的表,nagios_servicestatus,nagios_hoststatus,如果允许的话,可以考虑换到memory引擎,速度上那个是飞快,不过前提你的内存要足够大。
因为ndo的原因,最近也草草的看了下mysql相关的东西,相当的不专业。
阅读(2987) | 评论(0) | 转发(0) |