您的位置:首页 > 数据库 > MySQL

ndo入mysql的一些优化

2012-12-27 16:36 337 查看
ndo+mysql用的人还是挺多的,当监控节点多的时候,mysql经常先成为瓶颈,一旦它挂在那里,那整个nagios会因为等待ndo2db返回结果而挂住。所以,如果有必要的话,还是要对它进行一些优化。(http://blog.chinaunix.net/uid-17196076-id-2817707.html)

一、是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引擎,速度上那个是飞快,不过前提你的内存要足够大。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: