刘鹏飞,2021年4月加入去哪儿网DBA团队,负责公司的MySQL的管理和运维,以及数据库的自动化平台开发。具有多年的数据库管理和优化经验。
一、背景
去哪儿网数据库监控告警系统前期主要通过 Nagios+NRPE 插件来实现的。NRPE 是 Nagios 的一个功能插件,可以实现监控主机的 CPU 负载情况、磁盘使用情况等,通过不同的检测命令实现获取不同的监控指标数据。使用 NRPE,需要被监控主机上部署 NRPE 程序,Nagios 上安装 check_nrpe 插件。具体架构如下图所示。
流程说明:
Nagios 运行 check_nrpe 插件,定时通知 check_nrpe 检测哪些服务;
check_nrpe 通过 SSL 通道调用远端主机上的 NRPE 程序;
NRPE 接收到调用命令运行相应的监控脚本,获取相应的监控指标数据;
NRPE 将监控指标数据返回给 check_nrpe ;
check_nrpe 再将获取的数据返回给 Nagios ;
Nagios根据获取的监控数据,将告警信息通过 notification 插件发送到邮箱,电话等。
这里需要说明一下,熟悉 Nagios 的同学应该都清楚, Nagios 其实只是起到调度的作用。监控指标的获取,监控告警级别的判断,告警通知功能的实现都是通过相应的插件来完成的。那么这就带来了以下问题:
告警阈值不能灵活调整;
告警级别不能灵活调整;
告警屏蔽不支持多样化;
告警屏蔽延迟时间比较长;
告警的差异化支持不友好;
告警信息都从同一个通道中发送出来,不支持分组发送,导致无法区分哪些是重要紧急的告警信息。
DBA若要调整告警配置都涉及繁琐和批量的更改监控脚本,还有可能涉及重启 NRPE 。我相信每个人对于这样的操作都会厌恶至极,甚至会导致很多失误。
二、改进之路
既然现在的监控系统对于 DBA 来说不是很友好,那要如何解决呢?把现在的架构整个否定,选择其他监控系统,如 zabbix ,OpenFalcon 等?倘若整个架构替换就会完美吗?另外,整个架构替换的话,从被监控的成千上万的实例的监控获取到告警发送整个流程里的所有程序和脚本都要替换,无论从时间成本和人力成本考虑都太高了。那对于上面的问题,到底该怎么解决呢?
并且,通过上面的描述发现,我们遇到的问题,其实是报警效率低的问题,包括配置更改,更快速地发现需要解决的报警等等,而不是报警不准确,报不出来等问题,所以我们不需要去替换当前的监控报警系统,或者我们自己再去做一个报警系统,并且我们始终认为,我们应该做自己擅长的事情,报警系统并不是我们擅长的。
所以我们所考虑的是如果在当前系统基础之上,解决这些问题。并且尽可能地将我们 DBA 所擅长的融入到这个系统中去。
上面已经提及了,Nagios 其实就是起到调度作用,获取监控数据和发送告警都是通过插件来实现的,那是不是还可以通过插件来解决上面遇见的问题呢?若是给 notification 插件增加一个功能,使之能将监控信息写入到 Kafka 中,然后再增加一个程序实现从 Kafka 读取监控信息并进行告警判断和发送告警信息的功能,好像就能解决上面的问题了。这里所能体现出来的,就是 DBA 擅长的工作了,比如判断哪一个报警应该是要被快速解决掉的。改进后整个监控告警系统如下图所示:
架构改进说明:
整个架构从 notification 插件之前均无变化;
notification 插件其实可以不用实现告警发送的功能了,只需要实现将监控信息写入到对应的 Kafka 中;
增加 alarm 程序,alarm 程序实现告警阈值的灵活调整,告警级别的判断等,以及发送告警信息;
将告警配置统一标准化并存储到 MySQL 数据库中,修改配置只需修改对应表记录即可,另外 alarm 程序在处理监控信息过程中也会去查询 MySQL 数据库,找出对应的告警模板信息,告警屏蔽时间等;
为了防止 Kafka 消息堆积,以及 alarm 单点故障, alarm 程序可以部署在多台机器上,实现高可用,如图二中的示例是将 alarm 程序部署在两台主机上,分别为alarm1,alarm2;
所有的 NRPE 配置文件里的告警分级和阈值,可以保持目前不变,或者干脆都改为统一标准,亦或者降低标准,需要报的都报出来。需要修改相应配置时,只需要修改下游 MySQL 中的对应配置参数即可;
不紧急的报警,可以不报,只是将他们做个统计分析,然后以报表的方式发出来,然后自上而下地去解决问题。
alarm 的主要流程包含从 Kafka 获取监控数据,根据告警配置判断告警级别,将告警信息分组发送。alarm 的具体流程如下图所示。
1)获取监控信息
alarm 从 Kafka 获取监控信息,监控信息主要包含监控指标数据,监控获取时间,主机名,对应的模板名称等信息。
2)告警模板配置
告警模板分为全局配置和自定义配置,其中自定义配置可以实现主机层面的自定义配置和实例层面的自定义配置。这些模板配置信息均保存在数据库中,这样若要更改某个告警模板的阈值,或者某个主机/实例的告警配置都只需要更改对应的表记录即可。对告警模板的调整已经界面化,操作起来既方便又灵活,不用再批量繁琐地更改监控脚本。
告警模板信息主要包括以下信息:
模板名称,不同的告警模板对应不同的监控指标;
是否启动,可以灵活启停告警模板,不启用的情况下,获取到对应的监控信息不会在发送告警;
标识字段、比较方法和正则表达式,这为了识别监控数值,并进行告警级别判断;
告警值、严重值、电话值和夜间电话值是为不同的告警级别设置的不同阈值,通过和阈值的比较进行不同的告警分级,从而可以差异化选取告警媒介(邮件、QTalk 或者电话),发送到不同的组别,这样就便于 DBA 筛选重要紧急的告警;
电话阈值(秒),判定完告警级别,会再次判断该告警持续时长,若达不到模板里配置的时长,也不会发送告警,这样做是为了防止某些指标瞬时的变化然后又及时恢复导致的告警。
告警模板,如下图所示:
3)告警屏蔽和发送
告警屏蔽十分灵活,可以对某个主机或者某个实例屏蔽,也可以针对某一个监控项屏蔽,屏蔽时间范围也可自行灵活设置。这样告警屏蔽就具备了多样化,DBA 可以根据实际情况在需要时选择合适的屏蔽粒度或屏蔽时间进行设置。由于是直接修改的配置模板,所以前面提到的屏蔽延迟问题也就不存在了。
告警发送,在判定出告警级别后,会根据告警级别判断告警发送途径。目前使用的告警媒介有两种,QTalk(去哪儿网内部工具)和电话。其中发送到 QTalk 里的信息会根据告警级别(warning,critical,call)发送到不同群组,实现告警信息分级,便于区分重要紧急告警信息。
这里要特别说一下 call 级别的告警,call 级别的告警除了会发送 QTalk 信息外,还会进行语音告警。对于语音功能的实现,我们处理的方式是会先将 call 级别的告警再放入 Kafka 对应的另一个 topic 里,然后由语音告警系统统一调度。这样做是因为整个公司目前使用的是同一套语音系统,若是各自直接调用语音系统,容易导致语音系统堵塞。
三、智能化探索
去哪儿网数据库监控的智能化目前还处于初级的阶段,主要实现了告警管理、慢查询管理、磁盘空间管理。在告警信息发送前会加上一个链接,通过这个链接可以在手机端或者PC端调用智能化处理程序。
告警管理做到了告警屏蔽/开启功能,还能根据实际情况设置屏蔽时长。也可以选择屏蔽的粒度,是主机层面还是实例层面,亦或是单一的告警项,十分灵活。对于 DBA 要处理告警或进行实例维护时可以很便捷的管理告警,不用再繁琐的查找、操作。
需要注意,告警屏蔽的环节很关键。我们现在的告警屏蔽仅仅在 alarm 发送告警这一环节将告警过滤掉,而不影响 Nagios 对 check_nrpe 的调度,也就是不影响监控数据的获取,也不会影响告警级别判断等其他环节。这样就不会造成监控数据的丢失,带来的好处就是在以后做告警信息统计分析和多指标联合分析时,不会发生因为数据丢失而导致分析失效或者分析结果误差较大的情况。
在检测到监控信息里有慢查询时,会根据告警信息里包含的实例信息连接到对应的实例,查询出当前实例里执行时间最长且未结束的慢查询,然后将慢查询的相关信息,如连接用户、执行的具体 SQL 等,返回给管理界面,同时生成 kill 操作,这样 DBA 看到这些信息就能判断如何处理,是否可以 kill 。避免了 DBA 还要登陆到实例,然后执行查询语句的过程。同时也降低了发生误操作的概率。
或许有人会有疑问,不能直接在程序里自动kill吗?当然可以。但是执行多久的慢 SQL 自动 kill ,这个时长标准取多少呢?10s?100s?定义成多少总有不合适的地方。因为有的业务线执行的 SQL 耗时可能大部分都比较长,如 BI ,数据分析;有的业务线只有个别 SQL 耗时比较长。反过来想一下,若是能一杀了之,那是不是就能把对应的业务功能下线呢。
所以这里只是给出了一个处理方式,真正要解决慢 SQL 还要去判断某一慢 SQL 造成的影响,并将其优化掉。目前去哪儿网已经制定了一套慢查询风险指数模型,可以很好地去界定一个慢查询是不是真的有风险,或者风险有多大,这样就可以以上帝视角的方式,来管理所有的慢查询, 这样自上而下地去根本性地解决问题,效率和成效会非常高。
当我们发现磁盘空间剩余率不足时,通常会临时删除或者清空一些文件,以便能快速释放一部分空间。其实在我们做清理文件时基本可以分为两种情况,一种是能进行批量操作删除的,如清理数据库 binlog ;另一种就是只能单独处理,或删除或置空文件,如 MySQL 的错误日志等。所以我们在监控到数据库主机磁盘空间告警时,就可以分为两种情况进行统计和清理操作:
对目录级别的空间统计,这种目录里存放的都是同一类的文件,按照一定规律生成,清理时可以进行批量清理,最明显的就是存放 MySQL 的 binlog 的目录;
对文件级别的空间统计,这种文件所在的目录里面存放的文件没有规律性,清理时只能单独操作删除,有的只能置空不能删除,如 MySQL 的慢日志,错误日志等。
另外,数据库主机的目录结构已经进行了标准化规范。所以,我们就能抽象出一个配置模板,将那些可能会出现大文件的目录配置到模板中,并配置是进行目录级统计还是进行逐个的文件扫描统计。这样的直接好处就是能直接扫描确定的目录,不用再层层递归扫描,更不用全盘扫描,代价相对很低,并且更高效。
如图七展示的样例 ,收到磁盘告警后,自动化程序根据配置模板自动收集并上报的磁盘空间使用信息,DBA 在看到报警后就能很快的进行清理磁盘的操作,并判断出释放空间的大小,是否需要紧急地进行进一步的操作来解除风险。
四、写在最后
目前数据库的告警已经具备了基本的功能,以及初步的智能化。但是要想尽善尽美,还有很长很长的路需要我们去探索。
未来会在下面几个方面进行深耕:
告警信息的统计分析。通过分析历史的告警信息,获取各个告警类型告警频率和占比;分析出各个实例的告警分布情况,根据告警情况和监控指标对实例做进一步的健康诊断。这样可以从整体上了解集群实例的状态,更容易发现潜在问题。
多指标联合分析告警。目前的告警只是根据某一个指标进行判断,可能会有误报或者不准的情况。若将相关的指标的联合分析,更能体现实例的状况。如现在检测到 threads_running 达到阈值就会告警,但是实例负载并不高,一切正常,这就是一个无效的告警。有时候 threads_running 比平常高,但没有达到阈值,结果实例负载已经有较大的波动,有了变慢的现象,这时候又应该及时发出告警。所以有时对于单指标的告警并不能很好的反应实例状况,这时若将 threads_running 和磁盘 IO、cpu、锁等指标联合分析,能更好的发现问题,反应实例状况。
指标突变检测。有些时候数据库异常,从简单的指标数据值是无法判断出问题的,这时就需要检测一些指标的突变情况,如 QPS/TPS 突变、连接数突变等。相信很多 DBA 都遇见过,由于应用变更,突然发现数据库连接被打满了。查看监控连接数并不是瞬时被打满,也经历了一定时间,这时如果有这种突变检测能更早的发现问题。
如果字段的最大可能长度超过255字节,那么长度值可能…
只能说作者太用心了,优秀
感谢详解
一般干个7-8年(即30岁左右),能做到年入40w-50w;有…
230721