客户实践案例丨详解如何改造存储表分区,彻底解决Zabbix误告警现象
Zabbix 是一款常用的监控工具,它可以监控网络设备、服务器、应用程序等多种资源的状态。目前,使用 Zabbix 最大的瓶颈是数据库,维护好 Zabbix 的数据存储和告警,就能很好地应用 Zabbix 构建监控系统。
Zabbix 的数据主要存储在 history 和 trends 的2个表中,Zabbix 使用 SQL 删除查询从数据库中删除旧数据,可能会对数据库性能产生负面影响。随着时间推移,这两个表性能变差,我们非常容易收到误告警信息,严重影响查看真正出现问题的告警信息。
以上问题可以通过改造存储分区表轻松解决,实现快速清理历史数据,减少数据存储容量。下面通过一次成功的客户案例,向大家分享云掣快速定位 Zabbix 误告警原因 ➡️ 寻找解决方案 ➡️ 选择适合实际情景应用方案的全流程,详解存储分区表改造的整个过程,希望能够对面临同样数据库运维问题的人提供一定的支持与帮助。
背景
在维护客户监控系统的过程中,我们遭遇了一个极为棘手的状况。Zabbix 监控系统中,大量 Agent 不可达告警如潮水般涌来,然而令人费解的是,实际被监控端的 agent 状态明明一切正常,相关截图清晰地显示着这一矛盾情况。
经过深入调查,发现该问题的导火索是一次计划内的 RDS 重启维护操作。在此次维护之后,告警便接踵而至。但从数据库的各项指标来看,其运行状况又处于正常水平,毫无异样之处。这一异常现象无疑给监控系统的稳定性与可靠性带来了巨大的冲击,后续我们深入剖析这一问题的根源所在,并探寻行之有效的解决方案,以恢复监控系统的精准与稳定。
问题分析
首先,我们确认了当前的Zabbix架构:Zabbix Server、Zabbix Proxy和Zabbix Agent的分布式监控架构。这种架构的优势在于减轻Zabbix Server的负担,并实现集中式和分布式监控。
补充:
Zabbix Proxy可以代表Zabbix Server收集性能和可用性数据。 通过这种方式,Proxy可以自己承担一些收集数据的负载,并减轻Zabbix Server的负担。
此外,当所有Agents和Proxy都向一个Zabbix Server报告并且所有数据都集中收集时,使用Proxy代理是实现集中式和分布式监控的最简单方法。
我们按照层级关系排查问题
1. 首先第一个链路节点:Zabbix Agent
排查实际对应 Agent 主机运行状态正常,网络也均正常。
2. 中间链路节点:Zabbix Proxy
排查各监控指标没有明显异常。
3. 最外层链路节点:Zabbix Server
排查 Zabbix Server 主机相关监控指标,发现存在两处异常:
● utilization od Housekeeper internal processes 使用率已达 100%,如下图。
● Zabbix 误告警时,队列中有大量数据堆积,如下图。
进一步分析发现,实际误告警出现的时间刚好接近历史数据清理的时间,所以判断是历史数据过大,Housekeeper清理历史数据期间达到瓶颈导致出现大量数据队列堆积,从而触发了误告警。
补充:
Housekeeper作用:为了防止数据库持续增大,Zabbix有自动删除历史数据的机制,即Housekeeper,而在频繁清理历史数据的时候, Housekeeper进程突然开始繁忙。
处理方案
方案一:减少历史数据保留时长
既然是清理历史数据导致的,那么首先从历史数据入手,核查历史数据对应的数据库文件大小。
history: 185.94 GB history_uint: 242.71 GB
进一步确认这些历史数据的目前配置的保留时间,客户侧 Zabbix 历史数据保留时间为90天,历史趋势数据保留时间为 180天。
补充:
历史数据(history)和趋势数据(trends)是Zabbix中存储收集到的数据的两种方式。
历史数据:每一个收集到的监控数据, 趋势数据:按小时统计计算的平均值数据。
一般来讲,强烈建议将历史数据保留时长设置得尽可能的小。这么做可以让数据库不会因存储了大量的历史数据,导致超负荷运行。
可以选择长时间的保留趋势数据,来替代长期需要的历史数据。例如:设置成保留14天历史数据和5年的趋势数据。
为了短期内可以尽快解决该问题,首先和客户沟通是否可以减少历史数据保留时长,最终客户侧要求历史趋势数据至少保留 90 天。
所以这里首先将历史数据设置为 30 天。历史趋势数据设置为 90天。
但是实际观察下来发现,因为客户目前采集的数据量比较大,这个举措效果不是很明显,偶尔还是有误告警的情况。
方案二:存储分区表改造
为了彻底解决 Housekeeper 清理历史数据期间导致的误告警问题,我们决定将历史存储数据进行分区改造。
说明
当使用 MySQL 作为 Zabbix 的存储数据库时,在定期清理数据的时候,会消耗大量的服务器 CPU 和数据库的性能。因为删除的时候使用的是 Delete 语句清理,如果表的数据量很大,执行效率会变的非常差。不仅耗费大量的计算资源,还会引发数据库性能的衰退,最终累及整个监控平台的运行速度和响应。
将 Zabbix 底层表改造为分区表,Delete 清理数据的动作,变为 Drop 分区,从 DML 转化为 DDL 语句,对服务器和数据库负载影响减少了数倍,清理数据的动作也变的轻量化。
本篇文章下面介绍改造的整个过程。
准备工作
分区表在改造的时候,会全程锁表。根据历史经验,200G 的大表,改造为分区表需要 6 小时。Zabbix 一共有两张大表,大致需要 13 小时。所以不能直接到生产 Zabbix 数据库上执行,一般需要重新 clone 一台数据库,然后在 clone 数据库中进行分区改造,最后再切换到生产环境,这样在改造的时候,报警机制是可用的,切换的影响只有丢失 13 小时的监控数据。
如果使用的 RDS,可以直接使用基于时间点恢复 clone 实例。如果使用的是本地自建的 MySQL,可以使用 Xtrabackup 进行数据备份,然后还原到新实例。
分区改造
这一步,已经准备好了 clone 实例,此时就是对该实例进行分区改造。在存储过程创建代码这块可以修改历史数据和趋势数据的保留策略,例如下方表示保留 30 天的历史数据,保留 90 天的趋势数据。
连接数据执行 SQL 语句,这一步仅创建存储过程,所以非常快。
mysql -h mysql-host -u root -p '' < zbx_db_partitiong.sql
在存储过程第一次执行的时候,会把原表改为分区表,这一步需要消耗大量的时间,取决于你的数据量。
mysql -h mysql-host -u root -p '' --database Zabbix -e'CALL partition_maintenance_all('Zabbix');'
定时维护分区
改造为分区表后,清理数据的动作变成了分区的创建和删除,需要周期维护。这里推荐使用 MySQL 原生的定时调度功能,阿里云 RDS for MySQL 也支持使用定时调度。
确认是否开启 MySQL 定时调度功能:
SHOW VARIABLES LIKE 'event_scheduler';
创建定时调度任务:
CREATE EVENT zbx_partitioning ON SCHEDULE EVERY 12 HOUR DO CALL partition_maintenance_all('Zabbix');
查询任务执行情况:
SELECT * FROM INFORMATION_SCHEMA.events;
Zabbix Web 端配置禁用内部的Housekeeping
如果图片不明了,请按照以下步骤在 Zabbix 前端上配置管家:
● 导航到“管家”部分:“管理”→“一般”→“管家";
● 删除“历史记录和趋势”部分下“开启内部管家”中的复选标记;
● 在“历史记录和趋势”部分的“覆盖监控项趋势期间”上打勾;
● 在“历史记录和趋势”部分下,为趋势和历史记录定义“数据存储期”的天数(必须与数据库分区中配置的天数相同–历史记录应为60天,趋势图应为90天,如果您未更改脚本中的默认设置);
● 点击“更新”按钮。
结论
通过方案二的执行操作,将历史数据存储进行分区表改造后,"utilization od Housekeeper internal processes "从 100% 下降至 15% 左右,性能优化了 4 倍左右,并且从根源上彻底解决了 Zabbix 误告警问题。
云掣专注于可观测运维,致力解决企业上云难、用云难、管云难三大问题。基于云数据库提供7*24小时保障服务,提供开发支持、数据库体系规范、持续优化、数据库架构支持,保障企业数据库高效稳定运行。全面提升企业的运维效率和稳定性,助力企业完成云时代的数字化转型,满足客户在数据库管理和云迁移方面的多样化需求!
想了解或咨询更多有关云掣产品、服务、客户案例的朋友,戳我进入云掣官网。
参考资料
【1】https://bestmonitoringtools.com/zabbix-partitioning-tables-on-mysql-database/
拓展知识
HousekeepingFrequency介绍:
Zabbix 执行Housekeeping 的频率 (单位为小时)。
Housekeeping 负责从数据库中删除过期的信息。
注意: 为了防止 Housekeeper 负载过大 (例如, 当历史和趋势周期大大减小时), 对于每一个监控项,不会在一个 Housekeeping 周期内删除超过4倍 HousekeepingFrequency 的过期数据。 因此, 如果 HousekeepingFrequency 是 1小时, 一个周期内不会删除超过4小时的过期信息 (从最旧的数据开始) 。
备注: 为降低 Server 压力, Housekeeping 将在 Server 启动以后,延迟30分钟执行。 因此, 如果 HousekeepingFrequency 是1小时, Server 启动30分后执行第一次 Housekeeping , 然后按1小时为周期重复执行。从 Zabbix 2.4.0 以后有了这种延迟行为。
从 Zabbix 3.0.0 开始,可以设置 HousekeepingFrequency 为0来禁止自动 Housekeeping。 此时 Housekeeping 只能通过 Housekeeper_execute 启动, 在一个 Housekeeping 周期内删除的过期信息时长为从最后一次 Housekeeping 以来到配置周期的4倍,不少于4小时且不大于4天。