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 慢查询日志分析流程

  1. 采集日志:集中收集所有查询节点的日志到 ELK / Loki 或直接使用 grep 过滤。
  2. 提取慢查询:按耗时降序排列,筛选出 p99 以上的查询。
  3. 解析查询模式:识别高频出现的 metric 名称、标签组合、时间范围。
  4. 关联资源指标:将慢查询与 CPU、内存、磁盘 IO 时间线对齐。
  5. 标记瓶颈类型:区分是数据量过大、索引缺失、还是并发竞争。

示例: 使用 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 瓶颈定位流程总览

下图展示了从慢查询日志到查询分析器的完整瓶颈定位链路:

查询性能瓶颈定位流程 慢查询日志 耗时 > 阈值 查询分析器 分阶段耗时 / 数据源 资源指标 CPU / 内存 / IO 瓶颈分类 数据倾斜 / 全表扫描 / 缓存 优化方案 索引 / 缓存 / 分片 关键原则: 先慢日志 → 再分析器 → 最后资源指标

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,当慢查询数量超过阈值时自动触发告警,形成闭环治理。