慢查询监控是MySQL运维中非常重要的一项,它可以帮助分析线上数据库性能的抖动或者业务查询响应慢等情况。当集群和实例非常多的情况下,慢查询的收集和存储会变得比较困难,而且不太好做到实时的慢查询告警。常用方案介绍
1、慢日志收集
通常情况下会采用通过定时任务的方式使用pt-query-digest 将每个实例的慢日志收集写入到MySQL数据库。由于是定时任务触发,所以并不是实时的进行收集上报。2、慢日志统计
通过查询MySQL数据库可以根据host、port、user、指纹、时间范围等条件进行查询统计。3、慢日志告警
从MySQL中查询出慢日志然后匹配到对应的DBA和研发人员发送告警。但由于MySQL中数据是全量存在的只能根据时间范围进行批次查询,告警就无法做到实时。pt-query-digest的方法在采集的时候就已经不是实时了,再加上告警任务是按时间范围进行批次查询所以这套架构下的慢查询监控不能做到实时的监控
下面介绍一下多点数据库实时慢查询监控的实现思路。
多点实时慢查询监控整体架构

如上图,我们有一个监听slowlog的agent,这个agent主要是持续的对慢查询log文件进行tail,将每一个slowlog段作为一个list的iterm push到redis。每个agent可以监听所在机器的所有MySQL实例的慢日志,这样就把分散在各个机器上的日志汇集到了一个redis中。然后有一个消费端也就是slowlog推送服务,从redis中pop出组装好的慢日志,根据pop出的慢日志解析其中的host,port,dbname以及user,匹配到对应的dba或研发,将慢日志实时推送给对应的人员。同时按照host-port将慢查询存储为文件。这样就形成了一个流式的处理,再加上redis的全内存操作,速度极快,完全可以做到实时。采集端实现
' fill='%23FFFFFF'%3E%3Crect x='249' y='126' width='1' height='1'%3E%3C/rect%3E%3C/g%3E%3C/g%3E%3C/svg%3E)
我们可以看到慢查询日志一般是一段一段的记录的,所以我们以# Time行开始记录,直到遇到下一个# Time 将中间的一段作为一个整体push到redis,但这些信息远远不够,还需要额外加入MySQL的实例信息,后续才好进行分析,所以最终到redis中的数据应该类似下图:' fill='%23FFFFFF'%3E%3Crect x='249' y='126' width='1' height='1'%3E%3C/rect%3E%3C/g%3E%3C/g%3E%3C/svg%3E)
消费端实现
' fill='%23FFFFFF'%3E%3Crect x='249' y='126' width='1' height='1'%3E%3C/rect%3E%3C/g%3E%3C/g%3E%3C/svg%3E)
消费端做两件事情,第一将pop出来的消息根据ip:port为文件名进行日志归类存放,以便后续使用pt-query-digest对日志文件进行进一步统计分析。第二根据ip:port查询到对应的集群负责人和DBA,将慢查询通过短信或者邮件推送给对应的人员。前端展示
' fill='%23FFFFFF'%3E%3Crect x='249' y='126' width='1' height='1'%3E%3C/rect%3E%3C/g%3E%3C/g%3E%3C/svg%3E)
按集群维度+实例维度展示某时间段的慢日志大小,点击分析按钮可调用pt-query-digest对慢日志文件进行分析,输出结果如下:
' fill='%23FFFFFF'%3E%3Crect x='249' y='126' width='1' height='1'%3E%3C/rect%3E%3C/g%3E%3C/g%3E%3C/svg%3E)
' fill='%23FFFFFF'%3E%3Crect x='249' y='126' width='1' height='1'%3E%3C/rect%3E%3C/g%3E%3C/g%3E%3C/svg%3E)
这个实时信息就是从redis中pop出来的,可以进行实时的滚动展示,同时可以通过邮件等方式实时推送给订阅者。预告一波:今年10月24日下午14:00-18:00,D+Talks 2021多点技术大会将拉开帷幕,届时将在会上分享多点的数据库运维平台相关的topic,和大家一起探讨数据库运维的标准化、自动化方面的一些方法和思路,欢迎识别下图二维码参加线下活动,与行业大咖共同探讨!' fill='%23FFFFFF'%3E%3Crect x='249' y='126' width='1' height='1'%3E%3C/rect%3E%3C/g%3E%3C/g%3E%3C/svg%3E)