TiDB在中国银行Zabbix监控方案中

作者介绍:韩宇,中国银行信息科技运营中心工程师。本文的内容可能和之前的金融企业将TiDB应用在业务上的实践不同,下面主要介绍我们如何把TiDB应用在金融行业的后台运维监控上。Zabbix作为一个老牌的开源监控方案,长期被用于生产实践。但是原生方案一般会采用MySQL作为后端存储,无法应对更大规模的监控。TiDB兼容MySQL协议,可以替换MySQL从而增强Zabbix的大规模监控能力,实现新的监控方案TiZabbix。TiZabbix通过优化监控实施逻辑,弥补因TiDB和MySQL差异造成的诸多问题,成功完成了+监控对象和16T数据存储查询的实践。下文将从以下三部分展开:一是传统的Zabbix监控方案,二是TiDB在Zabbix中的应用,三是TiZabbix的优化提升。一、传统的Zabbix监控方案及主要问题Zabbix是一个比较老牌的开源监控方案,这里只做一个简单介绍,Zabbix主要分为四个部分:Agent:数据采集代理,部署于被监控服务器上;Server:Zabbix的服务端,用于数据的采集和发送告警等;Web:用于数据采集和告警规则等配置,前端数据展示和API调用;数据库:MySQL用的比较多,用于配置信息和监控数据的存储。当然了,随着Zabbix的版本的迭代升级,除了MySQL也支持了其他的数据库,在后面会简要的提到一些。传统的Zabbix监控方案主要有以下几个问题,这些问题都是由单机数据库MySQL引起的:数据库MySQL是单机的,因此不能支持较大量(指上几T量级的数据)的数据;由于这个的原因,所以监控对象的数量和数据存储时间不能兼得;官方给出了proxy的解决方案,想通过proxy来提升监控纳管被监控对象的能力,但是proxy最终也是要把数据发到最后面的主MySQL上,其实并没有减轻数据库的压力。由于MySQL对Zabbix的限制,所以后来考虑用TiDB在Zabbix中直接替换掉MySQL,来提升Zabbix的数据采集量。二、TiDB在Zabbix中的应用1.应用时间轴这里是一个简单的时间轴:年:用的单实例的Zabbix,用了MySQL,监控了+的Linux服务器,当时存储了60天的分钟级数据。年:使用ZabbixServer进行双实例部署,各监控+的Linux的服务器,尝试将历史数据用Python写入Elasticsearch。但是,由于中间用了Python的读取写入过程,不如直接往数据库里写些稳定。所以当时用了一段时间,没有继续用下去。年:开始尝试使用TiDB代替MySQL,这时的生产环境开始使用原生Zabbix,原生的Zabbix方案也已经支持Elasticsearch作为后端存储。但是考虑到TiDB兼容MySQL协议,且TiDB是分布式数据库,可能比Elasticsearch会有一些优势。再加上Elasticsearch在当时的易用性也不是很好,特别是升级的操作对于刚入门的用户来说是比较痛苦的,而TiDB的升级就比较平滑,因此,综合考虑后开始使用TiDB代替MySQL。年:通过解决若干的替换问题后,TiZabbix监控对象达到+,数据量达到15T。年:TiZabbix监控对象达到了+,数据量达到18T,每日采集的数据条目大概是14.5亿条。同时,稳定性也得到显著的提升,这里的稳定性,不是指单独TiDB的稳定性,由于TiDB官方建议用的硬件性能要求比较高,但是由于各种原因的限制,我们使用到的TiZabbix环境下TiDB的硬件性能不是很好,所以硬件性能的问题,会限制TiDB的稳定性。在年,通过解决了若干问题,在这些较差的硬件上,同样将TiDB的稳定性是达到了一个比较理想的水平。2.实践历程接着分享一下具体的实践历程,我们在这个过程中陆陆续续解决了一些问题,才达到了刚才说的18T的监控数据的一个相对稳定的状态。首先,一开始是不改动Zabbix的源码,半黑盒替换数据库。改源码是一个系统性的工程,难度比较大。为什么说半黑盒替换呢?因为虽然没有改源码,但是在遇到问题时,需要通过阅读源码来通过一些替换方案或者绕行方案来解决替换过程中遇到的问题。下面就是实践中遇到的一些问题。和原生不一样,监控对象自动注册我们改为使用API延迟注册,Zabbix自动注册功能是它实现监控自动化的一个重要功能。但是TiDB是乐观锁(较新的版本已经支持悲观锁了),和MySQL的悲观锁是有区别的,当大规模的自动注册时,它是有严重的事务冲突的,所以就把自动注册功能改为用串行的API的延迟注册,通过API调用的方法,来将新上的监控分区注册上来,解决事务冲突的问题。接着就遇到了History表的问题,因为Zabbix里几个History表是监控数据的存储表,是非常大的。当时一开始,我们用的是TiDB2.1版本,还不支持表分区,所以存储时间长了后,删数据的问题比较难处理。升级到3.0版本,支持了表分区,通过DropPartition来解决历史数据的删除问题。所以在用的过程中,对于大表的表分区还是非常重要的。接下来还遇到一个问题,Log类型的数据是一个长字符串,在2.1版本的时候,到了一定的数据量后发现所有数据都写入不进去。当时,看了TiDB的官方手册里提到写放大的问题,觉得可能是Log类型的长字符串引起的。对于监控来说,数值性的数据它的历史参考价值比较大,像Log的参考价值比较小。因此,把Log型的采集关掉后,数据库的写入就恢复了。规模更大了以后,又遇到了外键约束的问题。因为TiDB是不支持外键约束的,而原生Zabbix后端数据库是MySQL,是有外键约束的要求的,特别是在外键里,有一个主键和外键的级联删除功能,相当于从数据库层面实现而不是应用代码实现这个功能。所以,因为外键的问题也造成了某些因为Lowleveldiscovery(Zabbix里的自动发现功能)的问题,简单举例来说,就是比如说Linux和挂载点,需要发现每个挂载点来监控每个挂载点的磁盘使用量,这种自动发现的功能产生的告警就会因为外键的问题发生错乱。除了外键约束的问题外,又发生了数据无法写入的问题。后来阅读了Zabbix的源码,在源码中发现,在判断告警规则的时候,有一个锁缓存的操作,可以锁掉ZabbixServer上的缓存。因为ZabbixAgent采上来的数据是先缓存到ZabbixServer的内存里,锁缓存以后,缓存的东西就不往数据库里写了,因此,后端数据库就无法写入。最终因为这两方面的原因,我们决定把告警功能裁减掉,将TiDB用在Zabbix后,只用它来采集、存储和查询数据。但是告警去掉了,怎么来弥补这个功能呢?在生产环境上,我们通过使用ZabbixAgent的本身双写能力(双写到不同Server),往两个方向的Server上写数据。一个Server上对应的是MySQL,用来实现告警功能,它的告警不会受外键的影响,但是它的数据存储就特别特别少,可以解决性能问题。另一方向的数据把它写到对接TiDB的Server上,就不要告警功能,只要数据的访问和大规模存储。最终通过数据和告警的分离解决了这个问题。3.一些技巧接下来,简单说一下使用过程的一些小技巧。1)在设计过程中,架构要尽量的简单。Zabbix支持主Server上再放proxy,但是一开始使用,建议先不用proxy,因为proxy会引入复杂度。单ZabbixServer的情况下,按照现在的性能指标,保持现在的数据采集频率和存储时间,+的监控对象应该是没有问题的。2)Agent采用主动模式即Zabbixagentactive,这种模式可以有效减少Zabbixserver的压力。因为在被动模式下,Zabbixserver性能消耗比较多,而在主动模式下,相当于把压力下推到ZabbixAgent的采集端,这个压力对单个服务器来说是微乎其微的;但是如果都叠加压到Server上,Server肯定受不了的,所以通过选择active的模式,来减小Server的压力。3)将Zabbix里的配置项HistoryCacheSize设置为2G最大值,可以弥补硬件的不稳定性。刚才也提到了,因为没有用到TiDB建议的比较好的硬件,所以硬件性能的缺失就造成了TiDB的一些不稳定因素,有时数据写入会比较慢,就会积压到缓存里,把缓存设置的尽量大就会保证数据的不流失。虽然积压了,但是随着性能的恢复,数据是可以重新再写进去的,只是产生了一定的延时,但没有造成数据的丢失。4)API的调用不要过于频繁。因为API调用过程中权限的检查是要频繁的查和写同一个表的同一行数据,这会产生严重的事务冲突,特别是在TiDB乐观事务下,严重的事务冲突会拖垮数据库的。所以,API调用不要过于频繁,如果需要多进程,或者多线程的调用API,最好是多用几个SessionID,SessionID是权限检查的最小单元,这样可以避免这种情况。5)随着数据量的增大,Web的一些操作会失效,需要灵活的使用API。失效主要是因为数据库事务比较大,前端会超时,因此,当数据量比较大时,比如说要在前端大规模的改一些东西,这时就要灵活的使用API。因为API是一个自动化非常好的手段,通过灵活的使用API,会规避这个问题。4.TiZabbix方案优势我们通过以上的探索来解决了一些问题,完成了TiDB在Zabbix中的有效应用。1)监控的数据中台化方案。TiZabbix是用在监控数据的中台化方案,主要解决数据大量的采集、存储和查询,可以提供更大量的、更长时间监控的历史数据,方便我们进行数据分析、查询和一些复杂问题的定位。2)Zabbix-Server高效且支持多种数据采集方式。我们知道,原生的告警规则是比较简单的,只有通过较多历史数据的关联查询分析才能有效定位一些问题。同时,Zabbix-Server比较高效,单Server下我们用的是虚机(一般最大64G内存),它是支持+的Linux的采集的管理分区没有问题,而且它支持多种的数据采集方式,这就是一个很好的数据集成的支持。3)Zabbix-Web提供丰富的API,可以通过API来调用数据。4)TiDB本身就是良好的横向扩展能力,且易用性极高。通过横向扩展提高数据库的容量和性能,这样可以获取更多的数据和更长时间的存储。三、TiZabbix的优化提升上图是TiZabbix简单的架构图,ZabbixProxy在这里是没有用到的,但当规模更大的时候会使用它来分摊ZabbixServer的压力。因为在单ZabbixServer下,它的内存会是潜在的瓶颈,当被管理端多了后,对应Server的内存肯定会不断的增长,增长到一定程度后单机就无法再增大了,就需要proxy来分担Server的压力。所以,当达到更大的规模后proxy是需要引入的。架构图的右半部分是提供API的Web,相当于第三方的调用来消费监控到的数据。架构图最下面一层是TiDB,TiDB目前来看也是存在着一定的潜在的瓶颈,可能主要是并发冲突。因为用到的是比较差的硬件,肯定是要受点限制的,具体表现在并发的性能上会下降一些,不过这个也可以通过逻辑上的方案来规避一下,就是item(Zabbix的一个关键数据模型)。在一些极端场景下,自动产生的item会比较多,如果它不断的自动生成,相当于会出现写热点,然后会产生并发冲突,进而拖垮整个数据库。所以,在更大规模下,需要优化自动生成的item策略。将item的自动生成策略打散,不要在同一时间点生成过多的item,来缓解可能引起的并发冲突。当然,通过提升硬件的性能,也能够来弥补这个问题。以上就是关于TiDB在我们中国银行Zabbix监控方案中的应用,谢谢大家。


转载请注明:http://www.aierlanlan.com/rzfs/6374.html