ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Mycat监控实战:从命令行到Prometheus体系搭建

Mycat监控实战:从命令行到Prometheus体系搭建 做Mycat运维这些年我最深的体会是数据库中间件的监控比业务代码难太多。业务代码你打几条日志丢给ELK就能看个大概Mycat是数据库的统一入口你既得盯它的连接、线程、内存还得盯它背后一串MySQL节点的健康状态。我刚接手项目那会儿还是一行行敲show status、show connection去看数据是拿到了但总感觉像透过针眼看房间。后来陆续把Mycat监控工具真正落地才从“看得见”变成了“看得懂”。这一篇就专门讲监控适合那些正在用Mycat、又不满足于命令行快照的朋友。如果把项目从分片规则到读写分离都搭好了监控往往是最后补的一块。原因也很现实Mycat本身不强制你上监控业务不报错的时候你根本意识不到需要它。可一旦连接池打满、SQL慢查询堆积、后端主从延迟你再回去翻命令行已经晚了。监控的价值不是“出问题时看一眼”而是让问题在影响业务之前就被看到。所以这篇我会从Mycat自带的能力讲起再逐步落到监控工具选型、指标设计、告警配置和真实排障记录。1. 先把Mycat自带的监控家底摸清很多朋友一上来就找第三方监控工具结果发现工具和各种脚本都看不懂原因是对Mycat自身暴露了什么数据没有概念。其实Mycat的管理端口1822也好普通MySQL协议端口8066也好都提供了一套以show 开头的管理命令。这是最底层的监控能力也是所有外部监控工具的数据来源。1.1 一条命令一张快照我先把我常用的一组命令整理出来你可以在MySQL客户端里直接执行也可以连到Mycat的管理端口执行命令主要看什么关键字段show version版本号、启动时间VERSIONshow status整体运行状态MYSQL_STATUS、MAX_ACTIVE_CONNshow database逻辑库列表逻辑库名show datanode后端数据节点状态dataNode、dataHost、状态show command实时QPS、TPSquery、prepare、commit、rollbackshow connection前后端连接明细processor、host、port、stateshow threadpool线程池占用情况active_size、task_sizeshow cache缓存命中情况put、get、hit、missshow sql最近SQL统计执行次数、平均耗时、涉及节点show slow慢SQL记录耗时、SQL文本show processor每个处理器的负载读/写字节数、队列大小这里面show status和show command我用的最多。show status里能看到从启动到现在累计处理的请求数show command则是实时计数器你把两次查询的结果做个差值除以间隔秒数就能算出一个粗略的QPS。早期很多人就是这样手动估算流量的。show connection更偏排查用。它有前端连接应用连到Mycat的和后端连接Mycat连到MySQL实例的连接太多不一定是坏事但要结合state字段看。如果大量连接卡在Idle说明连接池闲着如果大量连接卡在Query或Updating那就要小心后端节点是不是出问题了。1.2 为什么命令行不够用靠命令能拿数据但这套机制有几个明显短板。第一它是“瞬时快照”。show status看到的只是当下这一刻的累计值没有时间轴。你无法回答“过去两个小时连接数是怎么走的”“昨晚的慢查询是从几点开始变多的”而这些才是故障根因分析最需要的东西。第二它没有告警能力。你可以每分钟跑一次命令把数字写进文件但没人能保证7乘24小时盯着。真正稳的方案是让监控工具自动采集、自动计算、超过阈值就通知人。第三它的数据是文本很难聚合。Mycat一旦重启很多累计计数就清零了。你要想在月度复盘时知道“上个月峰值QPS是多少”光靠命令行根本攒不下这些数据。所以我的结论是命令行可以作为即时检查手段但想形成完整的监控体系必须把数据采集到独立的监控工具里。Mycat官方提供的Mycat-web或者通用监控体系里的Prometheus都可以干这件事。后面我会把两条路都讲清楚。2. 监控指标选型抓关键而不是抓全量真正到了要搭监控的时候很多人容易犯一个错把所有能采的数据全部丢到看板上结果页面拉不到底有用的信息被淹没。我的经验是Mycat监控只需要抓四个维度连接、执行、资源、后端节点状态。2.1 连接维度前后端连接数永远是第一优先级连接数直接反映系统的承载水位。前端连接是应用跟Mycat之间的连接数量通常跟应用实例数、连接池配置有关后端连接是Mycat跟后端MySQL建立的连接数量往往决定了数据库能承受的压力。我一般会盯两个阈值。一是前端连接数超过预估值的80%就要看超过100%基本意味着应用侧的连接池配置偏大或Mycat处理不过来。二是后端连接数它的异常上涨通常是慢SQL堆积导致的。show status里的MAX_ACTIVE_CONN字段就是用来反映最大活跃连接数的如果你看到它高频撞顶说明连接资源已经绷得很紧了。这里有个容易误判的地方不一定连接数高就是故障。很多应用框架为减少建连开销会主动维持一批空闲连接尤其是后端连接池空闲连接多说明下面MySQL实例还扛得住。真正危险的是“活跃连接数”蹭蹭往上涨同时“空闲连接数”快速下降这时候才需要警觉。2.2 执行维度QPS、慢SQL、缓存命中率执行层面的指标直接反映Mycat这层中间件到底干了多少活。show command里有query、prepare、commit、rollback等字段query单位时间内发生的次数就是QPScommit加rollback再除以时间就是TPS。这两个指标不能只看绝对值要跟后端MySQL的监控对照着看。如果Mycat的QPS平稳但某个后端节点的TPS异常升高多半是数据热点打到了单个分片上。慢SQL是执行维度最重要的一项。Mycat的sqlSlowTime参数定义了慢SQL阈值超过阈值的SQL会被单独记录。我强烈建议你把慢SQL监控接到告警里因为Mycat里的慢SQL跟单机MySQL慢日志的含义不一样——它可能不是单条SQL真的慢而是这条SQL被路由到多个分片后总耗时被拉长了。换句话说你优化SQL本身可能没用得先看它有没有走分片键。缓存命中率则要看show cache。Mycat对全局表、主键查询等场景有缓存机制命中率高说明热点数据缓存效果好。但这个东西别盲目追求高很多查询根本不在缓存设计范围内命中率低不代表系统有问题要结合SQL类型一起判断。2.3 资源维度Java进程的JVM和线程池Mycat本质上是Java进程所以JVM指标必须纳入监控范围。堆内存使用率、Full GC频率、GC停顿时间这些数据直接决定了Mycat会不会突然“卡一下”。线程池指标同样重要。show threadpool里能看active_size和task_sizeactive_size高说明线程都在干活task_size高说明任务已经开始排队了。我见过一个案例后端Connection被慢查询占满结果SQL任务全部堆在Mycat的业务线程池里前端表现为“应用查MySQL超时”但MySQL其实一点不慢。这种问题如果不看线程池积压很难定位到Mycat这一层。资源维度的监控我建议用jstat、JMX或Prometheus的JMX exporter来做因为Mycat是标准Java应用通用Java监控方案都适用。2.4 后端节点维度数据节点和主从状态Mycat做读写分离之后后端主从的健康状态直接影响线上体验。你需要在监控工具里把每个dataHost对应的MySQL节点都加进去重点关注主从延迟、节点存活状态、复制线程运行状态。主从延迟尤其隐蔽。Mycat只负责按规则把读请求分发到从库它自己并不知道从库的数据到底新不新。如果你把实时的写操作立刻去从库读碰到延迟就会读到旧数据。监控上对主从延迟的阈值我习惯设得比较严超过1秒就要告警因为这个指标往往不是线性恶化的一旦开始涨就可能很快失控。3. 实操把Mycat监控工具完整跑起来指标想清楚了接着就是把一套能看的监控真正跑起来。我按从轻到重的顺序给三种落地方式开内置开关、部署Mycat-web、接Prometheus体系。你根据团队现有的监控设施选一种就行。3.1 第一步打开Mycat的统计和慢日志开关很多朋友部署完Mycat跑show sql发现结果为空慢SQL也查不到第一反应是命令不支持。其实多数情况下是统计开关没打开。在server.xml的system节点里默认有这几个配置项system property nameuseSqlStat0/property property nameuseGlobleTableCheck0/property property namesqlSlowTime100/property /systemuseSqlStat必须改成1才会开启SQL统计功能show sql和show slow才有数据。sqlSlowTime单位是毫秒表示超过多少毫秒算慢SQL我建议初调时先设100等系统稳定了再压到50。useGlobleTableCheck是全局表一致性检查开关不是监控项目但经常被人混淆别把它跟SQL统计混在一起。改完配置需要重启Mycat。这里有个经验sqlSlowTime改小之后Mycat会把超过阈值的SQL记录到日志文件但具体是logs/mycat.log还是logs/wrapper.log不同版本不一样。你直接搜日志里slow SQL关键字就能找到别傻等页面刷新。3.2 第二步部署Mycat-web监控平台Mycat官方配套的监控工具是Mycat-web很多人叫它Mycat-eye。它依赖ZooKeeper做节点注册部署完成之后浏览器打开就是一张能自动刷新的监控看板包含连接数、内存、QPS、SQL统计等核心图表不需要你再画看板。部署步骤不复杂下载Mycat-web的发布包解压到独立目录不要跟Mycat主程序放一起。准备一个ZooKeeper实例如果集群规模不大单机版就够。修改Mycat-web的配置文件把ZooKeeper地址指过去。启动ZooKeeper再启动Mycat-web。浏览器访问Mycat-web的默认端口常见是8082在页面里把Mycat实例地址填进去。我在部署时踩过两个坑。第一个是版本匹配问题Mycat-web版本太老时可能认不出新版本Mycat注册的节点信息界面上一直显示离线。第二个是ZooKeeper目录权限问题Mycat-web写不进ZNode导致页面能打开但没有任何数据。这两个问题排查起来都很费时间建议动手之前先确认包版本和运行用户权限。Mycat-web适合中小团队因为它开箱即用中文界面学习成本低。但它也有局限历史数据存储能力有限告警配置不算灵活如果你已经有完善的监控体系更推荐走Prometheus这条路。3.3 第三步把Mycat监控数据接到Prometheus体系Prometheus加Grafana现在是监控标配。Mycat官方没有专门的exporter但接法很简单核心思路是“定时执行show 命令把结果转换成Prometheus metrics格式”。我提供一个简化思路的脚本示例你可以直接改成Python或Go版本#!/usr/bin/env python3 import subprocess import time # 执行 show status 拿到原始文本 raw subprocess.check_output([ mysql, -h127.0.0.1, -P8066, -umonitor, -p123456, -e, show status; ], textTrue) out [] for line in raw.strip().splitlines(): if | not in line: continue parts [x.strip() for x in line.split(|) if x.strip()] if len(parts) 2: continue key, value parts[0], parts[1] if value.isdigit(): # 把最终指标输出成 textfile out.append(fmycat_{key.lower()} {value}) with open(/var/lib/node_exporter/textfile/mycat_status.prom, w) as f: f.write(\n.join(out) \n)这个示例默认你本机装有mysql客户端并且创建一个只有只读权限的监控账号。写出的mycat_status.prom文件用node_exporter的textfile collector就能被Prometheus抓到。同理show command、show datanode、show threadpool都可以走这套方式。如果你的Java环境支持也可以给Mycat进程挂上jmx_exporter直接暴露JMX端口这样JVM的堆内存、GC、线程数指标就不用额外采集了。两种方式不冲突我建议JMX管资源脚本管业务指标。3.4 第四步告警规则怎么配有数据没告警监控等于白搭。Prometheus里配告警规则很简单难点在阈值怎么定。我先给个示意配置groups: - name: mycat_alerts rules: - alert: MycatBackendConnHigh expr: mycat_backend_connections 300 for: 5m labels: severity: warning annotations: summary: Mycat后端连接数超过300 - alert: MycatSlowSQLSpike expr: rate(mycat_slow_sql_total[5m]) 10 for: 3m labels: severity: critical annotations: summary: Mycat慢SQL每5分钟超过10条阈值怎么定我建议取业务历史峰值数据再往上加20%到30%的余量。比如每周日晚8点是流量高峰后端连接数历史最高是240那告警阈值就设在300左右。千万别凭感觉随手填一个值不然不是天天误报就是真出事了也不响。告警路由上建议把Mycat的告警跟后端MySQL的告警放到一起方便值班同学在一个群里处理。毕竟Mycat的很多异常根因在MySQL光看Mycat数据容易绕弯路。4. 现场排查实录我这几年踩过的监控坑监控体系上线之后真正的考验才开始。这里挑几个我实际遇到过的典型问题每个都是能直接写进排障手册的那种。4.1 Mycat-web页面数据一直不刷新这个现象多见于刚部署完Mycat-web的时候。页面能打开左侧Mycat实例也显示在线但点进详情所有图表都是空的。排查路径我建议按三步走。先看ZooKeeper里有没有Mycat节点注册信息用zk客户端连上去找/mycat目录没有节点就是Mycat的JVM参数里没配上报地址。再看Mycat-web自身的日志重点找连接异常或解析异常。最后看Mycat的server.xml中useSqlStat是不是0因为Mycat-web拉取SQL统计时依赖这个开关它没打开SQL相关图表必然全空。我遇到过最隐蔽的一次是操作系统防火墙把8082端口对外关了Grafana里代理请求全部超时但本机访问一切正常。所以页面不刷新时别只盯Mycat配置先确认网络链路通不通。4.2 连接数告警误报把TIME_WAIT算成了活跃连接有一阵子我们的监控告警每天晚上都响报警内容是“后端连接数超过阈值”。我登上去一看show connection里并没有很多执行中的SQL但系统TCP连接数确实很高大量连接处在TIME_WAIT状态。这个问题的根子不在Mycat而在MySQL和应用侧连接池的交互。短连接频繁创建、销毁会在系统层面留下很多TIME_WAIT连接。监控工具如果直接抓系统TCP连接数很容易被这个数字误导。正确做法是区分清楚Mycat的show connection是逻辑连接代表真实的业务连接系统层的TIME_WAIT是TCP握手遗留状态不代表还有应用在用。告警应该盯前者不是后者。后来我们在指标采集脚本里只提取show connection中state ! Idle的连接数误报率立刻降下来了。这个经验也说明任何监控指标都要跟业务语义对上字段名看起来差不多实际含义可能差很远。4.3 慢日志打出来的SQL时间不准有段时间开发反馈Mycat记录的慢SQL明明耗时3秒MySQL自己的慢日志只有50毫秒两边对不上。排查之后发现Mycat的耗时包含“SQL路由后端执行结果集合并”的完整时间。这条SQL没有走分片键Mycat把它广播到了多个分片每个分片分别执行都很快但Mycat要等所有分片返回再把结果合并总体耗时自然被拉长了。这个不是Mycat的bug是分布式中间件的正常表现。所以看Mycat慢日志重点不是单条SQL执行多久而是这条SQL的数据访问方式是不是有问题。如果大量慢SQL都是没有分片键的查询说明业务写法或者分片键选型有问题光在MySQL侧加索引解决不了根本问题。4.4 缓存命中率“假性偏低”的问题show cache里的命中率也是容易误读的指标。缓存有PreparedStatementCache和结果集缓存等类型不是所有缓存都能命中。尤其是一些带随机条件的查询每次生成的SQL都不同缓存形同虚设命中率自然低。这不是故障但很多朋友一看命中率低就加缓存配置加完也没效果然后开始怀疑Mycat优化能力。我的建议是先分析查询模式。如果业务确实是大量重复的主键查询和全局表关联命中率应该高才对如果查询条件千变万化那命中率低就是常态别纠结认了就行。真需要性能提升优先考虑后端MySQL的优化和合理的分片键设计而不是死磕缓存参数。5. 监控数据反哺架构调整监控不只是用来出问题的它更大的价值在于帮你把架构调得越来越合理。我一般每季度会把Mycat的监控数据拉出来做一次复盘重点看两个地方。5.1 用SQL统计发现非分片键查询Mycat的show sql能统计每条SQL的执行次数和平均耗时。我会重点看那些执行次数高但没走分片键的SQL。这类SQL会让后端几乎所有节点都参与查询MySQL每个节点压力都不高但整体资源消耗是正常查询的几倍。发现这种情况第一选择不是改分片键分片键贸然改动代价太大。正确的做法有两条如果业务确实有固定的查询维度且值分布均匀可以在索引设计上做文章如果能改SQL让它先通过一个全局表或者维度表过滤出分片键再走分片查询往往一次SQL改写就能把压力降下来很多。5.2 用连接曲线规划连接池大小监控数据里的连接趋势是调整连接池参数最直接的依据。我会把前端连接、后端连接和业务流量画在同一张图上看三个曲线的相关性。正常情况是流量涨连接跟着涨如果流量平稳但连接一直涨就要考虑应用侧是不是有连接泄漏或事务过长。调整连接池时我有一个保守原则每调整一次观察一个完整业务周期不要上午改完下午又改。连接池太小会造成请求排队连接池太大会造成后端MySQL线程数虚高都是隐形问题。用监控曲线确认当前水位再动手比拍脑袋靠谱得多。5.3 我的一点个人体会把Mycat监控工具从头到尾搭起来之后我最明显的感觉是晚上睡觉踏实了。以前遇到线上抖动只能靠猜从应用到Mycat再到MySQL一条链上每一层都可能背锅。现在监控数据一拉连接、慢SQL、后端节点状态全都摊在眼前几分钟就能圈定范围。最后分享一个容易被忽略的小习惯监控工具的账号权限一定要收敛。不要直接用root账号去执行show 命令单独建一个只读监控账号既能避免误操作也方便后续审计。这个账号只做采集不做任何写操作放在专门的配置文件里跟业务配置隔离。做运维这些年我见过太多因为监控脚本权限过大而引发的连锁事故权限这东西永远是能给多小就给多小。
返回列表