4. 存储层故障排查:时序数据库写入瓶颈、查询超时、磁盘IO打满的排查方法

时序数据库(TSDB)是监控系统的核心存储组件,其性能直接决定告警延迟、查询响应与数据完整性。本章聚焦 Prometheus 与 InfluxDB 两类主流 TSDB,从写入瓶颈、查询超时、磁盘 IO 打满三个维度,给出架构视角的排查路径与根因定位方法。

核心原则:时序数据库的故障通常表现为“写入积压 → 查询排队 → IO 过载”的连锁反应。排查时应先确认故障面(写入/查询/IO),再逐层下钻至具体组件(WAL、Compaction、索引、分片)。

4.1 写入瓶颈排查

写入瓶颈的典型现象:指标数据出现断点、Prometheus remote write 报 503、InfluxDB 写入延迟飙升。排查路径分为三层:客户端限速 → 服务端队列 → 存储引擎背压。

排查层 关键指标 Prometheus 命令/端点 InfluxDB 命令/端点
客户端限速 写入速率 vs 配置上限 rate(prometheus_tsdb_out_of_order_samples_total[5m]) SHOW STATS FOR 'write'
服务端队列 WAL 积压、Appender 等待 prometheus_tsdb_wal_queue_size _internal.monitor.shard.write_points_ok
存储引擎背压 Compaction 延迟、内存映射压力 prometheus_tsdb_compactions_failed_total SHOW STATS FOR 'engine'
快速定位技巧:若 prometheus_tsdb_head_series 持续增长但 prometheus_tsdb_head_chunks 不增长,说明写入被 WAL 阶段阻塞,优先检查磁盘 IO 与 WAL 目录挂载类型(推荐 XFS 或 ext4,避免 NFS)。

4.2 查询超时排查

查询超时通常由索引扫描过大、全表扫描或并发查询排队引起。Prometheus 与 InfluxDB 的查询路径差异较大,需分别对待。

4.2.1 Prometheus 查询链路

  • Step 1:检查查询范围与时间跨度。大跨度查询(如 30d)会触发大量 block 合并扫描。
  • Step 2:查看 prometheus_tsdb_queries_total 与 prometheus_tsdb_query_duration_seconds 分位数。
  • Step 3:确认是否命中 --query.max-concurrency 限制(默认 20)。
# 查看当前活跃查询
curl http://localhost:9090/api/v1/status/active_queries

# 查看查询延迟分布
prometheus_tsdb_query_duration_seconds{quantile="0.99"}

4.2.2 InfluxDB 查询链路

  • Step 1:检查查询是否触发全表扫描(无时间范围或 tag 过滤)。
  • Step 2:查看 SHOW QUERIES 识别慢查询。
  • Step 3:确认 max-concurrent-queries 与 query-timeout 配置。
# 查看当前运行中的查询
SHOW QUERIES

# 终止超时查询
KILL QUERY <query_id>
常见陷阱:InfluxDB 的 SELECT * 且无 WHERE time 子句会触发全表扫描,导致内存溢出。建议在查询中始终指定时间范围,并使用 LIMIT 限制返回行数。

4.3 磁盘 IO 打满排查

磁盘 IO 打满是 TSDB 故障中最具破坏性的场景,通常由 Compaction 风暴、WAL 写入放大或查询临时文件溢出引起。排查需区分读写 IO 与IO 等待。

IO 类型 根因 排查命令 缓解措施
写 IO 打满 WAL 写入 + Compaction 合并 iostat -x 1 观察 %util 与 await 调整 storage.tsdb.retention.size 限制总数据量
读 IO 打满 大查询扫描多个 block iotop -o 定位进程 增加 --query.max-samples 限制扫描样本数
IO 等待高 磁盘性能不足或 RAID 降级 sar -d 1 查看 svctm 升级 SSD / 分离 WAL 与数据盘
时序数据库磁盘 IO 打满排查流程 磁盘 IO 打满告警 iostat -x 1 检查 %util 写 IO 打满 读 IO 打满 IO 等待高 检查 WAL 与 Compaction 检查大查询与 block 数 检查磁盘类型与 RAID 分离 WAL 盘 / 限制数据量 / 升级 SSD 提示:Compaction 风暴可通过限制单次 Compaction 并发数(InfluxDB: max-concurrent-compactions)缓解

4.4 典型故障场景与根因对照

故障现象 根因 快速验证 修复动作
写入延迟持续上升 WAL 队列积压,磁盘 IO 成为瓶颈 prometheus_tsdb_wal_queue_size > 1000 增加 WAL 批量写入大小,或分离 WAL 到独立 SSD
查询返回超时 查询扫描过多 series,触发 OOM prometheus_tsdb_series_fetched_total 突增 添加更精确的 label 过滤,或降低 query.max-samples
磁盘 IO 100% 但写入量不大 Compaction 线程数过高,或数据碎片严重 iostat -x 显示 await > 50ms 降低 Compaction 并发,或手动执行 OPTIMIZE 合并分片
InfluxDB 写入报 engine: cache snapshot too big 内存中缓存积压,触发写入背压 SHOW STATS FOR 'cache' 查看 snapshotSize 增加 cache-max-memory-size,或减少写入并发

4.5 架构级优化建议

  • 存储分离:将 WAL 目录与数据目录分别挂载到不同磁盘(WAL 使用低延迟 NVMe,数据使用大容量 SSD)。
  • 写入限速:在采集端(如 Prometheus Agent 或 Telegraf)配置 max_samples_per_send 与 capacity,避免突发写入压垮 TSDB。
  • 查询超时兜底:设置合理的 query-timeout(Prometheus 默认 2m,InfluxDB 默认 30s),并启用慢查询日志。
  • Compaction 窗口:在业务低峰期(如凌晨)手动触发 Compaction,避免与写入高峰重叠。
监控自愈建议:在告警规则中加入 prometheus_tsdb_wal_corruptions_total 与 influxdb_tsm1_filestore_disk_bytes,实现存储层故障的提前发现。