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

全部博文(19)

文章存档

2010年(4)

2009年(15)

我的朋友

分类: LINUX

2009-08-06 14:25:45

   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) |
给主人留下些什么吧!~~