2. 查询性能瓶颈识别:慢查询日志与查询分析器实战
在 Golden Signals 指标查询场景中,性能瓶颈通常表现为查询延迟突增、资源消耗飙升或超时错误。本章系统讲解如何通过慢查询日志和 Prometheus / Thanos 查询分析器两大工具链,精准定位瓶颈根因。
2.1 慢查询日志:第一道防线
慢查询日志是数据库和查询引擎内置的“黑匣子”,记录执行时间超过阈值的查询语句。对于 Prometheus 和 Thanos,慢查询日志主要来自以下组件:
| 组件 | 日志位置 | 关键字段 | 默认阈值 |
|---|---|---|---|
| Prometheus | --log.level=debug 或查询日志文件 |
query, duration, series_fetched |
无内置慢查询阈值,需自定义 |
| Thanos Querier | --query.log-file 或 stdout |
query, duration_ms, store_hints |
可通过 --query.timeout 间接控制 |
| Thanos Store Gateway | 访问日志(--http.config) |
series, chunks, duration |
无默认阈值 |
最佳实践: 在 Prometheus 启动参数中添加
--web.enable-query-log 开启查询日志;Thanos Querier 使用 --query.log-file=/var/log/thanos/query.log 持久化慢查询记录。
2.2 慢查询日志分析流程
- 采集日志:集中收集所有查询节点的日志到 ELK / Loki 或直接使用
grep过滤。 - 提取慢查询:按耗时降序排列,筛选出 p99 以上的查询。
- 解析查询模式:识别高频出现的 metric 名称、标签组合、时间范围。
- 关联资源指标:将慢查询与 CPU、内存、磁盘 IO 时间线对齐。
- 标记瓶颈类型:区分是数据量过大、索引缺失、还是并发竞争。
示例: 使用 jq 解析 Thanos 查询日志,提取耗时超过 5 秒的查询:
cat query.log | jq 'select(.duration_ms > 5000) | {query, duration_ms, timestamp}'
2.3 Prometheus 查询分析器:深入查询执行计划
Prometheus 从 v2.28 开始内置了 查询分析器(Query Analyzer),通过 /api/v1/query_exemplar 或 --web.enable-query-log 配合 pprof 可以获取查询执行细节。Thanos 则通过 Query Frontend 提供更完整的分析能力。
| 分析维度 | Prometheus 原生 | Thanos Query Frontend |
|---|---|---|
| 执行时间分解 | 仅总耗时 | 分阶段耗时(拆分、合并、去重) |
| 数据源分布 | 不提供 | 每个 Store 的响应时间与数据量 |
| 缓存命中率 | 不提供 | 前端缓存、索引缓存命中情况 |
| 序列扫描量 | series_fetched 字段 |
每个 Store 的 series 和 chunks 数量 |
2.4 查询分析器定位瓶颈的典型模式
通过分析器返回的指标,可以快速归类以下瓶颈模式:
- 数据倾斜:某个 Store 响应时间远高于其他 Store,说明数据分布不均或该 Store 负载过高。
- 全表扫描:
series_fetched数值巨大(超过 10 万),且查询未使用标签索引。 - 缓存失效:查询分析器显示缓存命中率为 0%,且查询时间范围跨度大。
- 合并开销:Thanos 查询分析器中“合并阶段”耗时占比超过 60%,说明数据碎片化严重。
注意: 不要仅依赖总耗时判断瓶颈。一个 10 秒的查询可能是由于单个 Store 超时(数据倾斜),也可能是由于查询前端合并大量小分片(合并开销)。必须结合分阶段耗时数据。
2.5 瓶颈定位流程总览
下图展示了从慢查询日志到查询分析器的完整瓶颈定位链路:
2.6 实战案例:从慢查询到根因
某生产环境 Thanos 查询延迟从 2 秒飙升至 30 秒,通过以下步骤定位:
| 步骤 | 操作 | 发现 |
|---|---|---|
| 1 | 查看 Thanos Querier 慢查询日志 | 发现 rate(container_cpu_usage_seconds_total[5m]) 耗时 28 秒 |
| 2 | 启用查询分析器,查看分阶段耗时 | “合并阶段”耗时 22 秒,占比 78% |
| 3 | 检查 Store 响应分布 | 其中一个 Store 返回了 80% 的数据,其他 Store 数据极少 |
| 4 | 分析数据分布 | 该 Store 的哈希环配置错误,导致数据倾斜 |
| 5 | 修复 | 重新均衡 Store 数据分片,查询延迟降至 1.8 秒 |
关键命令: 使用 Thanos 查询分析器查看分阶段耗时:
# 通过 HTTP API 获取查询分析结果
curl "http://thanos-querier:10902/api/v1/query?query=rate(container_cpu_usage_seconds_total[5m])&analyze=true" | jq '.data.stats'
2.7 常见瓶颈模式速查表
| 瓶颈模式 | 慢日志特征 | 分析器特征 | 推荐优化 |
|---|---|---|---|
| 全表扫描 | series_fetched > 100k |
无索引命中,数据源扫描量巨大 | 添加标签索引,缩小时间范围 |
| 数据倾斜 | 单个 Store 超时 | 某个 Store 响应时间 > 其他 Store 总和 | 重新分片,调整哈希策略 |
| 缓存失效 | 查询时间范围跨度大 | 缓存命中率 < 10% | 增大缓存 TTL,使用预聚合 |
| 合并开销 | 查询涉及大量小分片 | 合并阶段耗时 > 60% | 减少 Store 数量,合并小分片 |
| 并发竞争 | 同一时间大量慢查询 | 查询队列堆积,CPU 高 | 限流,增加查询节点 |
2.8 自动化瓶颈检测脚本
将以下脚本加入定时任务,自动扫描慢查询日志并告警:
#!/bin/bash
# 自动检测 Thanos 慢查询并输出 Top 10
THRESHOLD_MS=5000
LOG_FILE="/var/log/thanos/query.log"
cat $LOG_FILE | jq -r 'select(.duration_ms > '$THRESHOLD_MS') | [.timestamp, .duration_ms, .query] | @tsv' \
| sort -t$'\t' -k2 -rn \
| head -10 \
| awk -F'\t' '{print "时间: "$1" | 耗时(ms): "$2" | 查询: "$3}'
进阶: 将上述脚本输出接入 Prometheus Alertmanager,当慢查询数量超过阈值时自动触发告警,形成闭环治理。