从零到一:sql_exporter实战指南
1. 为什么需要sql_exporter第一次接触数据库监控时我盯着MySQL里每天增长的订单数据发愁。领导要实时看到注册用户数、异常订单率难道要我每天手动跑SQL导出Excel直到发现sql_exporter这个神器才明白原来数据库监控可以这么简单。sql_exporter本质上是个翻译官它把数据库里的业务数据转换成Prometheus能理解的指标格式。比如你把用户表里count(*)的结果变成user_count指标把订单金额sum()变成order_amount_total。这样就能用Grafana做酷炫的实时看板或者设置当日注册用户1000这样的告警规则。适合三类人使用运维同学不想为每个业务需求写定制化监控脚本开发同学需要暴露服务内部的关键业务指标数据分析师希望自动化获取日报数据源我见过最聪明的用法是用它监控电商大促期间的库存变化。通过实时追踪inventory_remaining指标运营能第一时间发现爆款商品库存见底。2. 环境准备与安装2.1 硬件与软件要求虽然sql_exporter用Go编写相当轻量但根据我的踩坑经验建议准备测试环境1核CPU/1GB内存足够实测每秒20次查询无压力生产环境2核CPU/2GB内存建议限制最大连接数避免拖垮数据库兼容性方面我实测过这些组合MySQL 5.7/8.0 Prometheus 2.30PostgreSQL 12 VictoriaMetricsSQLite3 Grafana Cloud注意Oracle数据库需要单独安装OCI驱动Windows系统建议用Docker运行2.2 三种安装方式对比方法一直接下载二进制文件推荐新手# Linux系统 wget https://github.com/free/sql_exporter/releases/download/0.5/sql_exporter-0.5.linux-amd64.tar.gz tar -zxvf sql_exporter-*.tar.gz cd sql_exporter-* # Mac系统用这个 wget https://github.com/free/sql_exporter/releases/download/0.5/sql_exporter-0.5.darwin-amd64.tar.gz方法二Docker运行适合生产环境docker run -d \ -p 9089:9089 \ -v /path/to/config:/config \ ghcr.io/free/sql_exporter:latest方法三源码编译需要Go环境git clone https://github.com/free/sql_exporter.git cd sql_exporter make build个人建议从二进制包开始我在早期用Docker时遇到过权限问题二进制文件直接./sql_exporter就能跑起来。3. 配置文件深度解析3.1 主配置文件拆解先看一个我优化过的sql_exporter.yml示例global: scrape_timeout: 8s # 必须比Prometheus的scrape_timeout短 scrape_timeout_offset: 1s # 安全缓冲时间 min_interval: 30s # 避免高频查询打满数据库CPU max_connections: 5 # 根据数据库连接池调整 max_idle_connections: 2 target: data_source_name: mysql://monitor:Passw0rdtcp(db-prod:3306)/order_db?charsetutf8mb4 collectors: [user_metrics, order_stats] collector_files: - /etc/sql_exporter/collectors/*.yml关键参数经验scrape_timeout如果Prometheus设了10s超时这里建议8smin_interval业务指标通常30s-1分钟足够财务类关键数据可以设15s连接数配置要根据数据库负载调整曾经因为max_connections10把测试库拖垮3.2 指标收集器实战在collectors目录下我们创建两个业务指标文件用户指标(user_metrics.yml)collector_name: user_metrics metrics: - metric_name: active_users_today type: gauge help: 当日活跃用户数 values: [cnt] query: SELECT COUNT(DISTINCT user_id) AS cnt FROM user_activity WHERE last_active_time CURRENT_DATE()订单指标(order_stats.yml)collector_name: order_stats metrics: - metric_name: order_amount_by_status type: counter help: 各状态订单总金额 key_labels: [status] values: [amount] query: SELECT status, SUM(amount) AS amount FROM orders WHERE created_at DATE_SUB(NOW(), INTERVAL 1 DAY) GROUP BY status几个实用技巧用代替|可以避免SQL中的换行问题关键业务指标建议添加WHERE时间限制金额类指标用counter类型可以自动处理重置问题4. 部署与验证4.1 启动服务的正确姿势生产环境推荐用systemd管理# /etc/systemd/system/sql_exporter.service [Unit] DescriptionSQL Exporter Afternetwork.target [Service] Usermonitor ExecStart/opt/sql_exporter/sql_exporter \ --config.file/etc/sql_exporter/sql_exporter.yml \ --web.listen-address0.0.0.0:9089 \ --log.levelinfo [Install] WantedBymulti-user.target启动后检查日志的小技巧journalctl -u sql_exporter -f # 实时查看日志 curl -s localhost:9089/metrics | grep -v # # 快速检查指标4.2 Prometheus集成示例在prometheus.yml中添加scrape_configs: - job_name: sql_exporter scrape_interval: 30s static_configs: - targets: [sql-exporter:9089] relabel_configs: - source_labels: [__address__] target_label: instance replacement: 订单数据库监控常见问题排查如果看到context deadline exceeded错误检查scrape_timeout设置no metrics collected可能是SQL语法错误先用客户端工具测试SQL指标消失可能是数据库连接断开检查max_idle_connections5. 高级技巧与优化5.1 性能优化方案在大数据量场景下我总结出这些优化手段查询优化-- 原始慢查询 SELECT * FROM orders WHERE create_time DATE_SUB(NOW(), INTERVAL 7 DAY) -- 优化后使用索引字段 SELECT COUNT(*) FROM orders WHERE create_time BETWEEN 2023-01-01 AND 2023-01-02配置优化# 分批查询大数据表 metrics: - metric_name: large_table_stats query: SELECT column, COUNT(*) FROM huge_table WHERE id BETWEEN ? AND ? params: [[1,100000], [100001,200000]] # 自动分片查询5.2 监控指标设计规范根据Google SRE经验建议遵循这些原则黄金指标请求量如user_login_attempts错误率如order_failed_ratio持续时间如payment_processing_time业务指标- metric_name: shopping_cart_conversion type: gauge help: 购物车转化率 query: SELECT COUNT(CASE WHEN statuspaid THEN 1 END)/COUNT(*) AS rate FROM shopping_carts避免的陷阱不要监控会频繁清零的计数器避免过于细粒度的标签如user_id警惕指标基数爆炸用rate()处理高频变更6. 真实业务场景案例6.1 电商大屏监控这是我们在双11使用的配置片段- metric_name: realtime_gmv type: counter help: 实时成交金额 values: [amount] query: SELECT SUM(actual_payment) AS amount FROM orders WHERE pay_time UNIX_TIMESTAMP(CURRENT_DATE()) - metric_name: hot_items_top10 type: gauge help: 热销商品TOP10 key_labels: [item_name] values: [sales] query: SELECT name AS item_name, COUNT(*) AS sales FROM order_items GROUP BY name ORDER BY sales DESC LIMIT 10配合Grafana的Stat面板和BarGauge可以做出实时更新的战报大屏。6.2 异常检测配置通过Prometheus的告警规则groups: - name: business.rules rules: - alert: HighFailureRate expr: | rate(order_status_failed[5m]) 0.05 for: 10m labels: severity: critical annotations: summary: 订单失败率超过5% (当前值: {{ $value }})这套配置帮助我们提前发现了支付通道异常避免了大规模客诉。关键是要用rate()函数处理计数器而不是直接使用原始值。