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

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_bytesRSS 内存< 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 限制
大规模处理高基数标签、流式聚合、按日期分区

扩展阅读