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