强曰为道
与天地相似,故不违。知周乎万物,而道济天下,故不过。旁行而不流,乐天知命,故不忧.
文档目录

VictoriaMetrics 完全指南 / 10 - 性能调优

10 · 性能调优

本章目标

  • 了解 VictoriaMetrics 的性能指标体系
  • 掌握内存、CPU、磁盘的调优方法
  • 学会排查性能瓶颈
  • 掌握大规模场景的优化策略

10.1 性能监控指标

10.1.1 关键性能指标

指标 说明 健康范围
vm_ingest_rows_inserted_total 总写入行数 持续增长
vm_slow_inserts_total 慢写入数 接近 0
vm_slow_queries_total 慢查询数 接近 0
vm_active_timeseries 活跃时间序列 稳定或缓慢增长
vm_concurrent_inserts 当前并发写入 < maxConcurrentInserts
vm_concurrent_selects 当前并发查询 < maxConcurrentRequests
vm_free_disk_space_bytes 剩余磁盘 > 20%
process_resident_memory_bytes RSS 内存 < allowedPercent 设定

10.1.2 性能监控查询

# 写入吞吐率(samples/s)
rate(vm_rows_inserted_total[5m])

# 慢写入率
rate(vm_slow_inserts_total[5m])

# 活跃时间序列数
vm_active_timeseries

# P99 查询耗时
histogram_quantile(0.99, rate(vm_request_duration_seconds_bucket[5m]))

# 缓存命中率
vm_cache_entries{type="storage/tsid"} / 
(vm_cache_entries{type="storage/tsid"} + vm_cache_misses_total{type="storage/tsid"})

10.2 内存优化

10.2.1 内存分配控制

# 设置内存限制(推荐物理内存的 60-70%)
victoria-metrics -memory.allowedPercent=60

# 或指定绝对值
victoria-metrics -memory.allowedBytes=16GB

10.2.2 内存使用构成

VictoriaMetrics 内存构成:

┌──────────────────────────────────────┐
│           总内存分配                  │
├──────────┬───────────┬───────────────┤
│ 数据缓存  │ 索引缓存   │ 查询缓冲     │
│ (40-60%) │ (20-30%)  │ (10-20%)     │
│          │           │              │
│ 最近写入  │ 倒排索引   │ 查询执行     │
│ 的数据    │ 热数据     │ 临时缓冲     │
└──────────┴───────────┴───────────────┘

10.2.3 减少内存使用

# 1. 减少活跃序列数
# 检查不需要的高基数标签
curl 'http://localhost:8428/api/v1/status/tsdb' | \
    python3 -c "
import json, sys
data = json.load(sys.stdin)
for item in data['data']['seriesCountByLabelName'][:20]:
    print(f\"{item['name']:30s} {item['value']}\")
"

# 2. 使用 relabel 丢弃不需要的指标
# prometheus.yml:
metric_relabel_configs:
  - source_labels: [__name__]
    regex: "(go_.*|process_.*)"
    action: drop

# 3. 降低采集频率
# scrape_interval: 30s(而不是 15s)

10.2.4 OOM 排查

# 查看 OOM 历史
dmesg | grep -i "oom\|killed" | tail -20

# 查看 VM 内存使用趋势
curl -s 'http://localhost:8428/api/v1/query?query=process_resident_memory_bytes' | \
    python3 -m json.tool

# 预防措施:
# 1. 设置 systemd 内存限制
# /etc/systemd/system/victoria-metrics.service
[Service]
MemoryLimit=16G
# 或使用 cgroup v2
MemoryMax=16G

# 2. 设置 VM 内存限制
victoria-metrics -memory.allowedBytes=14GB

10.3 CPU 优化

10.3.1 CPU 使用分析

# 查看 VM 进程 CPU 使用率
rate(process_cpu_seconds_total{job="victoria-metrics"}[5m]) * 100

10.3.2 查询优化

# 限制并发查询数
vmselect -search.maxConcurrentRequests=16

# 限制查询超时
vmselect -search.maxQueryDuration=30s

# 限制返回序列数
vmselect -search.maxUniqueTimeseries=500000

10.3.3 写入优化

# 增加写入并发
vminsert -maxConcurrentInserts=64

# 使用 protobuf 格式(比文本格式更高效)
# 使用 remote_write 而不是 /api/v1/import/prometheus

10.4 磁盘 I/O 优化

10.4.1 文件系统选择

文件系统 推荐程度 说明
ext4 ⭐⭐⭐⭐ 成熟稳定,适合大多数场景
XFS ⭐⭐⭐⭐⭐ 大文件性能优秀,推荐大数据量
ZFS ⭐⭐⭐ 压缩优秀但内存开销大

10.4.2 I/O 调度器

# 查看当前调度器
cat /sys/block/sda/queue/scheduler

# SSD 推荐使用 none/mq-deadline
echo "none" | sudo tee /sys/block/sda/queue/scheduler

# HDD 推荐使用 cfq
echo "cfq" | sudo tee /sys/block/sdb/queue/scheduler

# 持久化(重启后生效)
echo 'ACTION=="add|change", KERNEL=="sd[a-z]", ATTR{queue/scheduler}="none"' | \
    sudo tee /etc/udev/rules.d/60-io-scheduler.rules

10.4.3 挂载选项

# SSD 推荐挂载选项
# /etc/fstab
/dev/sda1 /var/lib/victoria-metrics ext4 defaults,noatime,nodiratime,discard 0 0

# noatime:不更新访问时间,减少写入
# nodiratime:不更新目录访问时间
# discard:启用 TRIM,延长 SSD 寿命

10.4.4 磁盘空间管理

# 查看数据目录大小
du -sh /var/lib/victoria-metrics/data/*

# 查看 Part 数量(过多说明合并不及时)
ls /var/lib/victoria-metrics/data/big/ | wc -l

# 强制触发合并(不推荐,通常让后台自动处理)
# 可以临时增加 -finalMergeDelay 来延迟最终合并

10.5 网络优化

10.5.1 TCP 调优

# /etc/sysctl.d/99-vm-network.conf
net.core.somaxconn = 65535
net.ipv4.tcp_max_syn_backlog = 65535
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fin_timeout = 15
net.core.netdev_max_backlog = 65535

# 生效
sudo sysctl -p /etc/sysctl.d/99-vm-network.conf

10.5.2 文件描述符限制

# /etc/security/limits.conf
victoriametrics soft nofile 65536
victoriametrics hard nofile 65536
victoriametrics soft nproc 32768
victoriametrics hard nproc 32768

# systemd 服务中
[Service]
LimitNOFILE=65536
LimitNPROC=32768

10.6 大规模场景优化

10.6.1 高基数标签处理

# 问题:user_id 作为标签导致基数爆炸
http_requests_total{user_id="12345"}  # 100 万用户 = 100 万序列

# 解决方案:
# 1. 在 Prometheus 端 relabel 去掉高基数标签
metric_relabel_configs:
  - source_labels: [user_id]
    target_label: user_bucket
    regex: "(.{2}).*"
    replacement: "${1}xx"  # 只保留前2位

# 2. 使用 exemplar 代替标签
# 3. 应用层聚合后再暴露

10.6.2 按日期分区索引

# 启用按日期分区索引(默认开启)
victoria-metrics -disablePerDayIndex=false

# 优势:
# 1. 删除过期数据更快(直接删除目录)
# 2. 查询时间范围缩小到具体日期目录
# 3. 备份更灵活(可以按日期备份)

10.6.3 流式聚合

# 使用 vmagent 的流式聚合减少写入量
# /etc/vmagent/stream-aggr.yml
- match: 'http_requests_total'
  interval: 1m
  outputs:
    - total    # 1m 的总计
    - count    # 1m 的计数

10.7 性能基准测试

10.7.1 写入性能测试

# 使用 vmagent benchmark
# 生成测试数据
curl -s 'http://localhost:8428/api/v1/status/tsdb'

# 使用 Prometheus promtool 进行基准测试
# 或使用 VictoriaMetrics 自带的 benchmark

# 简单测试脚本
for i in $(seq 1 10000); do
    echo "benchmark_metric{host=\"host-$i\",region=\"cn\"} $(( RANDOM % 100 ))" >> /tmp/bench.txt
done

# 写入并计时
time curl -X POST \
    -H 'Content-Type: text/plain' \
    --data-binary @/tmp/bench.txt \
    'http://localhost:8428/api/v1/import/prometheus'

10.7.2 查询性能测试

# 测试查询耗时
time curl -s 'http://localhost:8428/api/v1/query?query=rate(benchmark_metric[5m])'

# 批量查询测试
for i in $(seq 1 100); do
    curl -s "http://localhost:8428/api/v1/query?query=benchmark_metric{host=\"host-$i\"}" > /dev/null
done

10.8 性能调优清单

类别 项目 检查/优化
内存 allowedPercent 设为物理内存的 60-70%
内存 活跃序列数 监控并控制在合理范围
CPU 并发限制 设置合理的 maxConcurrentInserts
CPU 查询超时 设置 search.maxQueryDuration
磁盘 文件系统 XFS 或 ext4,noatime 挂载
磁盘 I/O 调度 SSD 用 none,HDD 用 cfq
磁盘 剩余空间 保持 > 20%
网络 fd 限制 设置 LimitNOFILE=65536
网络 TCP 参数 调优 somaxconn 等参数
查询 标签过滤 使用精确标签避免全扫描
查询 时间窗口 缩短 range vector 窗口

本章小结

要点 内容
内存 控制活跃序列、设置内存限制、排查 OOM
CPU 限制并发、优化查询、使用 protobuf
磁盘 选择 SSD、XFS 文件系统、noatime 挂载
网络 调优 TCP 参数、增加 fd 限制
大规模 处理高基数标签、流式聚合、按日期分区

扩展阅读