OceanBase在传统监控数据存储的应用| 优秀征文分享

编者按:“让技术被看见 | OceanBase 布道师计划”由OceanBase主办,ITPUB社区协办,面向广大开发者的年度征文活动。全年 4 轮,以季度为周期进行优秀文章评比,每年 1 届,以年为单位进行最佳布道师评选。目前,首轮技术征文获奖文章已评选出炉,本篇内容为「OceanBase 布道师计划」优秀文章之一,作者:YoKing Ma

活动仍在进行中,欢迎感兴趣的小伙伴点击「官网链接」进入活动官网,了解活动详情或进一步投稿。

*官网链接:https://open.oceanbase.com/blog/essay-competition

评委点评:

老鱼(组长):   文章介绍了公司选用 Zabbix 监控系统的背景、遇到的问题、优化思考及最终选择 OceanBase 的过程,通过实际案例展示了 OceanBase 在处理大规模监控数据时的性能和成本效益,为同类企业提供了迁移经验。

章芋文       -       墨天轮:   本文深入探讨了 OceanBase Zabbix 监控数据存储中的应用,通过宁波新能源上市公司的实际案例,展示了从 MySQL 迁移到 OceanBase 的全过程及其带来的显著效益。文章条理清晰、逻辑性强,从监控架构介绍到 MySQL 的局限性,再到 OceanBase 的优势分析和部署实践,逐步揭示了 OceanBase 的高效性和实用性。具体性能提升和空间节约的数据支持,进一步证明了其在企业级应用中的实用价值。总体而言,这篇文章技术含量高,实践指导性强,对数据库专业人士和企业决策者具有很高的参考价值。           

屠敏-CSDN: 文章分享在传统监控数据存储中引入 OceanBase 的实践过程,清晰地阐述了现有架构的痛点以及 OceanBase 的优势。通过对比 MySQL 架构,作者展示了 OceanBase 在性能、可扩展性和高可用性方面的实践。整体内容实用且具有一定深度,为监控数据存储领域的技术探索提供了一些思路与启发。  

封仲淹 -OB :文章从一个非常具体的场景出发 , 整体上给用户一个新的解决方案 zabbix + oceanbase 的方案 , zabbix 用户和 occeanbase 用户一个新的思路 , 整个文章中 , 细节满满 , 非常详实 ; 在文章中 , 详细的描述了之前 zabbix + mysql 所遇到各种细节问题 , 并介绍如何进行选型 , 对比候选系统 , 最终使用 oceanbase 获得收益 .

正文:

笔者从事于一家总部位于宁波,业界领先的新能源上市公司,公司业务涵盖光伏新能源产品的开发、制造及销售。

作为产值百亿的企业,监控系统是重要的IT管理工具之一,对保障企业业务连续性、预告风险有重要意义。2022年,公司选用Zabbix为企业监控系统,对公司分布在国内外的服务器、操作系统、中间件、数据库、网络设备等进行指标监控;对集团业务系统设置监控预警,确保集团所有系统异常时准确告警;对IT设施的巡检、事件的回溯提供指标数据支撑,便于IT管理人员可以快速获取系统中各个组件的历史数据。

监控业务架构介绍

之所以选择Zabbix是因为其开源,且经过多年发展,不仅架构稳定还具备 监控万物 的能力,适合我们这种以传统架构为主,云原生架构比例很低的企业。公司内部相关IT人员也有Zabbix使用经验,上手门槛较低。

彼时,笔者刚加入公司,对刚上线的Zabbix监控系统做持续且深度的优化和改造,不断提升监控系统的及时性、准确性。由于Zabbix底层数据库使用MySQL 8.0,被MySQL的架构限制,因此,很快就出现了问题。

基于MySQL的监控业务架构痛点

第一个问题,架构高可用瓶颈,无论选择哪种架构,都不尽人意。

  • 主从架构的问题:
    • 非读写方式,与单点的性能无差异不推荐。主节点故障后,需要停机切换,还需要校验主从节点的数据差异,所以不推荐。
    • 读写分离方式有2种改造方式,一是改造DAL层代码,这种方式影响后续版本功能的迭代,不推荐;二是引入如 ProxySQL的中间件,但增加了一层组件,在性能和可靠性上有所降低。
  • 双主架构的问题:
    • 单写是我们目前采用的方式,节点上套用一层keepalived作为虚拟地址,方便切换。
    • 双写的话需要控制写入行的ID,避免主键冲突和数据冗余。需要改造,不推荐。
  • MGR架构的问题:
    • 一致性强,但需要配合如ProxySQL之类的中间件实现读写分离。在实际测试中,MGR容易产生雪崩效应,即一个节点掉出后,可能导致整个集群崩溃。

所有采用复制方式的架构最大的问题点在于,Zabbix的写入量很大,binlog不能保留太久(非常占用磁盘空间),如果复制关系断开太久会导致主从节点之间无法找到同步位点,无法重新同步上。

第二个问题,读写冲突。Zabbix的写入量很大,在业务高峰时段,运维人员和业务人员查询监控数据、history数据向trends数据转换、告警比较等,很容易产生读写冲突(乐观锁)。但Zabbix还有一个管家服务,会定期清理过期的监控数据,这容易造成悲观锁,使数据库性能急剧下降。在数据量不断增大的同时,这个冲突会越来越明显。

第三个问题,容量问题。尽管对监控项的数量、保留时间做了大量的改造,但仍有大量的数据需要保存下来。运行1年多,Zabbix的数据库已经超过1TB,最大单表数据量超7亿。数据本身的容量只是问题中的其一,其二是InnoDB的binlog。

基于监控架构痛点,我们需要结合业务情况进行优化,下面是我们对优化的思考。

优化MySQL难以解决根本问题

在众多优化案例里,笔者挑选了一个典型的数据优化案例来分享。

在制作Zabbix监控模板时,其中Linux操作系统监控模板的监控项就多达100个,面对公司2000+生产级别服务器,监控项规模达到了20w个,假设每隔5分钟对所有的监控项收集一次数据,那么,每小时数据库库中将有 20w*(60/5)=240w  笔数据要写入history表。

5分钟采集一次是一种理想情况,因为采集间隔变大后,数据的精度会降低。对于一些流量数据、CPU、内存、I/O等使用率数据,用户往往要求以较高的精度采集,采集间隔可能是在1分钟左右,这样的代价是产生了更多的监控数据。

同时考虑到  history  到  trends  转换,每小时从 hisoty  和  history_unit  表中取出完整1小时的监控值进行运算后(min、avg、max),分别  insert  到  trends  和  trends_unit  表中。

1727347610

这个过程中,查询到的结果集大、运算量大,需要大量的缓存,往往引起MySQL的临时表或临时表文件创建过快、磁盘I/O过大、占用SWAP、引发大事务等问题。

随着数据量的增大,以及上文提到的事务悲观锁冲突,导致在清理历史数据时,往往会清理任务失败,进而历史数据越积越多。同时,锁表的问题导致在环境中无法使用dump方式进行备份,只能使用物理备份。但在使用物理备份时,由于清理历史数据的过程中使用delete方式,造成主要业务表中的空间未得到正常释放,产生碎片,在备份前需要进行碎片整理,使得备份业务推进起来非常艰巨。

大批量的insert、delete操作使服务器的binlog变得庞大,导致存储压力很大。调小后,如果主从一断,主库上的binlog位点很快就会循环覆盖,导致从节点要重新恢复才能加入到集群。

对于上述问题,结合Zabbix数据库中的数据表,我们就需要通过优化以下数据表来解决问题。

表名 作用 数据类型
history 存储原始的历史数据 数字(浮点数)
history_uint 存储原始的历史数据 数字(无符号)
history_str 存储原始的短字符串数据 字符型
history_text 存储原始的长字符串数据 文本
history_log 存储原始的日志字符串数据 日志
trends 存储每小时统计数据(趋势) 数字(浮点数)
trends_uint 保持每小时统计数据(趋势) 数字(无符号)
auditlog 审计日志表

其中,以 history 开头的表为存储历史数据,trends开头的是趋势数据。历史和趋势是在Zabbix中存储数据的两种方法。

从索引开始

history表中存在2个时间字段,一个是clock,另外一个是ns,接收item值时的时间值存放在两个字段内,大于1秒的部分存放找clock字段单位是秒(s),小于一秒的部分存放在ns字段单位是纳秒(ns)。

两个字段相加的值才是接收item值时的时间值,一般不用关心小于1秒的部分。但是,在Zabbix自己做统计时很多查询中都用到了这两个字段,而这些表中,并没有在ns上面做索引,导致了全表扫描,所以我们将history表进行改造:

CREATE TABLE `history_old` (
  `itemid` bigint(20) unsigned NOT NULL,
  `clock` int(11) NOT NULL DEFAULT '0',
  `value` double NOT NULL DEFAULT '0',
  `ns` int(11) NOT NULL DEFAULT '0',
  KEY `history_1` (`itemid`, `clock`) BLOCK_SIZE 16384 LOCAL) DEFAULT CHARSET = utf8mb4CREATE TABLE `history` (
  `itemid` bigint(20) unsigned NOT NULL,
  `clock` int(11) NOT NULL DEFAULT '0',
  `value` double NOT NULL DEFAULT '0',
  `ns` int(11) NOT NULL DEFAULT '0',
  PRIMARY KEY (`itemid`, `clock`, `ns`)) DEFAULT CHARSET = utf8mb4
其余history表的改造参照上面的方法

表分区

针对history系列表和trends系列表进行分区,定期create 分区和drop 分区。在做分区管理时,遇到三个问题。

第一,因为监控数据表的数据量太大,直接在源表上操作风险很大,执行效率也会很低。所以采用了创建新表,然后将原表中的数据 insert  /*+ ENABLE_PARALLEL_DML PARALLEL(2) */ …… select …… 的方式处理(这里用到了OB DML的并行,具体可以参考https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000001050810),但发现部分数据量少的表还能够导数成功,大表、业务繁忙的表根本无法执行。

第二,如果我们使用dump方式去备份还原表,中间停机时间要很久。

第三,使用 DataX做数据同步的话,什么时候追平数据,如果中途停止,找最后位点的难度很大。

MySQL参数优化

在Zabbix中使用频度最高的就是将最新的数据写入数据库,按一定的时间间隔,将历史数据(history)转换趋势数据(trends),删除过期的历史数据,以及IT运维人员查询监控数据、报表(grafana)等操作。查询(排序、汇总、计算)、增删(大事务)会极大地消耗MySQL数据库的性能,使业务的处理时间变长。最简单的优化方案就是优化MySQL的innodb buffer pool、query_cache_size、tmp_table_size、innodb_log_buffer_size、 sort_buffer_size、read_buffer_size、join_buffer_size、binlog_cache_size的大小,尽可能将数据留在内存中,加快数据的处理速度。

但是无论如何优化buffer,也不能无限制的增大,当达到物理内存的上限时,就需要去扩容内存。同时,大量的大事务会过度消耗磁盘I/O(当脏页达到一定量的时候就会落盘,落盘就会产生I/O),加剧数据库的压力。底层物理设备的扩容会涉及停机、迁移等中断服务的事件,也是额外增加成本。

可见,在MySQL及操作系统的调优和扩容硬件的方法始终会有尽头或者瓶颈,不是最优解,我们需要寻找新的出路。

寻找新的出路

对于新的数据存储方案,我们希望除了能够解决现有架构瓶颈和业务痛点外,还需要具备三个条件:

1.     必须兼容MySQL的语法、函数与表达式、数据类型、表分区、字符集、字符序。

2.     具备HTAP能力,能够在基于关系型数据结构在数据引擎层面处理好TP和AP的关系。

3.     在不依托于其他技术手段的情况下具备高可用、多活能力。

由于Zabbix server 支持 MySQLPostgreSQL,但团队中没有人熟练驾驭 PostgreSQL,同时,在Zabbix的 MySQL 数据库上已经开发了比较多的应用、报表,如果贸然将数据库从MySQL切换成PostgreSQL,需要对之前的应用、报表做再开发,因此,暂时不考虑 PostgreSQL,于是将选型的范围放在兼容 MySQL 模式的数据库。

上文提到我们同时在使用InnoDB引擎,MySQL的TokuDB引擎作为InnoDB引擎的优化升级版本,就成为了我们选型数据存储方案中的备选。

首选还是考虑目前热度较高的新兴数据库,比如 TiDB、华为GaussDB和openGauss、OceanBase、达梦数据库

  • TiDB不支持MySQL的存储过程、外键,首先排除。
  • openGauss基于 PostgreSQL,与PostgreSQL数据库一样,作为第二梯队方案。
  • 华为GaussDB需要付费购买,暂时不考虑。
  • 达梦数据库需要付费购买,暂时不考虑。

OceanBase兼容MySQL,支持分布式,而且开源,可以进行下一步调研。

在兼容性的综合考量下,将 TokuDB引擎OceanBase作为优选方案。

对比项 TokuDB OceanBase
部署难易度 较容易 较容易
容灾架构 主从 分布式
数据压缩比
信创支持 支持
性能对比 优化了写入,但读性能缺少依据 未测试

综合考虑下,由于TokuDB读能力不满足预期,OceanBase支持HTAP、多活高可用,以及社区活跃,有非常多的参考资料,容易上手。因此,我们最终决定使用OceanBase。

上线OceanBase

我们按照官方文档执行部署,过程中遇到了一些小问题,通过查询官方文档、咨询社区技术人员等方式逐一解决(后续我会把部署过程分享到博客中,大家可以拍砖、借鉴)。

总的来说,OceanBase的上线流程较为顺利,从 MyySQL 迁移到 OceanBase非常容易。因为我们用的是OceanBase 社区版,所以,在迁移前无法使用迁移评估(OceanBase Migration Assessment,OMA)来对迁移过程进行评估,只能依靠经验来判断,在社区的官方人员和社区用户群朋友们的帮助下,我们在迁移前做了如下检查,供大家参考。

1727348341

相关各个节点的解释参见 官方文档。此外,上文中提到的在Zabbix的history相关表,trends相关表需要实现表分区。分区管理需要定时任务,否则管理员定期维护分区的工作量很大。在MySQL中,我们可以通过Event+存储过程的方式来实现自动化。而由于OceanBase中没有event,这似乎又要碰壁了。俗话说:“当门关上的时候,会给你开一扇窗”,因此,我们可以使用OceanBase 的ODC(开发者中心。OceanBase Developer Center)来实现,这是一个开源的企业级数据库协同开发平台。里面集成了“分区计划”的模块,可以将其看作MySQL中的Event+存储过程方案的Plus版本。具体可以看我之前的博客:https://open.oceanbase.com/blog/12521093139

新库新征程

在写本文时,我们的Zabbix监控系统已经在OceanBase中运行了半年,相比之前使用MySQL时,从资源配置上来讲,在获取相同性能的情况下,可以大幅降低硬件平台的投入。

1727348390

最初,由于OceanBase兼容MySQL,公司的开发人员和系统管理人员对于数据迁移并没有表示反对,在迁移过程中,OceanBase的高可靠、HTAP等能力使笔者在与业务系统运维部门沟通迁移计划时都比较顺利,迁移后带来的性能提升和80%的空间节约,也让业务部门非常满意。

在性能提升方面,最直观的感受是之前在查询周期较长的历史数据(几周或几个月)时,通常需要好几秒(至少4秒)时间才能将数据渲染出来,现在运行在OB上之后,基本上点击完后就可以立即加载出统计图;另外一个感受就是,以前zabbix有各种各样的性能告警,频度也比较高,自从迁移到OB上之后,此类告警明显减少。

总而言之,OceanBase是一个符合我们预期的数据库平台,目前,我们也在不断探索和实践OceanBase的新功能。以下,我将结合公司业务场景与OceanBase的功能进行简单总结。

此外,OceanBase丰富的生态工具也为我们带来了更加自动化、更加便捷的运维管理能力。

首先,OCP 为数据库的管理提供了很多实用的功能:

1727348486

1727348516

其次,OMS支持 OceanBase-CE、MySQL、PostgreSQL、TiDB、Kafka 和 RocketMQ 等多种类型的数据源与 OceanBase 社区版进行实时数据传输,以及 OceanBase 社区版 MySQL 租户间的数据迁移。

最后,ODC作为开发者中心,提供了许多便捷的功能,比如:

憧憬未来

对于OceanBase的这些特性,结合我们实际的业务,未来会将更多的库迁移到OceanBase上面来。目前正在进行的有生产设备数据采集系统(下称:数采系统)、报表系统的迁移。

数采系统的需求也是类似于Zabbix,特点是:

报表系统的特点是:

当然,一切美好的背后,仍然是有存在不足的地方,执行计划不仅难读,还抖动、恶化,导致SQL在执行时候不稳定,而且系统日志理解困难,另外对于中文的支持还是有提升空间,我们在测试obdumper时,遇到了中文表名备份失败的问题(目前社区还在分析,临时方案是回退到了一个旧版本来解决)。

结语

OceanBase的功能非常强大是事实,每一个事务都在不断进步。从我们试用到使用OceanBase的过程中,有“坑”也有惊喜,遇到问题,先看手册,自己思考。如果自己想不明白可以再社区的问答板块和用户答疑群寻求帮助,社区的老师会及时答复(相较于其他开源社区,OceanBase的及时性和准确性要好很多)。

OceanBase还在不断发展,对于4.3版本中的列存、物化视图等功能还等着我们探索,道阻且长,行则将至。



请使用浏览器的分享功能分享到微信等