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

VictoriaMetrics 完全指南 / 16 - 最佳实践

16 · 最佳实践

本章目标

  • 掌握容量规划的方法论
  • 建立生产环境的标准化规范
  • 了解不同规模场景的最佳架构
  • 学会持续优化监控系统

16.1 容量规划

16.1.1 容量规划流程

┌────────────────────────────────────────────────────┐
│              容量规划流程                            │
│                                                    │
│  1. 评估需求                                       │
│     ├── 活跃时间序列数                              │
│     ├── 采集间隔                                   │
│     ├── 数据保留期                                  │
│     └── 查询并发量                                  │
│                                                    │
│  2. 计算资源                                       │
│     ├── 磁盘空间 = 序列 × 样本大小 × 天数           │
│     ├── 内存 ≈ 序列 × 1KB                          │
│     └── CPU = 写入核 + 查询核                       │
│                                                    │
│  3. 选择架构                                       │
│     ├── < 100 万序列 → 单节点                       │
│     ├── 100 万 - 1000 万 → 单节点(高配)或集群     │
│     └── > 1000 万 → 集群版                         │
│                                                    │
│  4. 部署验证                                       │
│     ├── 基准测试                                   │
│     ├── 压力测试                                   │
│     └── 监控告警                                   │
└────────────────────────────────────────────────────┘

16.1.2 磁盘空间计算

磁盘空间 = 活跃序列数 × 每样本字节数 × 每天样本数 × 保留天数 × 压缩系数

示例:
  活跃序列 = 500 万
  每样本字节 = 0.2 bytes (VM 平均压缩后)
  每天样本数 = 86400 / 15 = 5760
  保留天数 = 90
  压缩系数 = 1.3 (索引 + 开销)

  磁盘空间 = 5,000,000 × 0.2 × 5760 × 90 × 1.3 / 1,000,000,000
           ≈ 67.4 GB

16.1.3 不同规模资源配置参考

规模 活跃序列 采集间隔 保留期 配置方案 月成本估算
小型 < 50 万 30s 30 天 单节点 2C/4G, 50GB ~¥200
中型 50-500 万 15s 90 天 单节点 8C/16G, 500GB ~¥800
大型 500-2000 万 15s 180 天 集群版 6 节点 ~¥5,000
超大型 > 2000 万 10-15s 1 年+ 集群版 15+ 节点 ~¥20,000

16.1.4 网络带宽规划

写入带宽 = 活跃序列 × (metric_name + labels + timestamp + value) / 采集间隔

示例:
  序列数 = 100 万
  平均每序列 payload = 200 bytes
  采集间隔 = 15s

  写入带宽 = 1,000,000 × 200 / 15 = 13.3 MB/s ≈ 107 Mbps

16.2 生产环境规范

16.2.1 部署规范

规范项 推荐配置
操作系统 Ubuntu 22.04 LTS / Debian 12
文件系统 XFS 或 ext4,noatime 挂载
磁盘类型 SSD (NVMe 最佳)
内存 60-70% 分配给 VM
绑定地址 127.0.0.1:8428(通过反向代理暴露)
systemd 使用 cgroup 限制资源
日志 JSON 格式,集中收集

16.2.2 systemd 服务文件模板

# /etc/systemd/system/victoria-metrics.service
[Unit]
Description=VictoriaMetrics Time Series Database
Documentation=https://docs.victoriametrics.com/
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=victoriametrics
Group=victoriametrics
WorkingDirectory=/var/lib/victoria-metrics

ExecStart=/usr/local/bin/victoria-metrics \
    -storageDataPath=/var/lib/victoria-metrics/data \
    -httpListenAddr=127.0.0.1:8428 \
    -retentionPeriod=90d \
    -memory.allowedPercent=60 \
    -dedup.minScrapeInterval=15s \
    -loggerLevel=INFO \
    -loggerFormat=json \
    -envflag.enable=true \
    -envflag.prefix=VM_

ExecStop=/bin/kill -SIGTERM $MAINPID
Restart=on-failure
RestartSec=10
TimeoutStopSec=30

# 资源限制
LimitNOFILE=65536
LimitNPROC=32768

# cgroup v2 资源限制
CPUQuota=200%
MemoryMax=16G
MemoryHigh=14G

# 安全加固
NoNewPrivileges=yes
ProtectSystem=strict
ProtectHome=yes
PrivateTmp=yes
ReadWritePaths=/var/lib/victoria-metrics /var/log/victoria-metrics

[Install]
WantedBy=multi-user.target

16.2.3 监控规范

# 必须监控的指标
alerting_rules:
  - vm_health:
      - InstanceDown        # 服务存活
      - TooHighMemoryUsage  # 内存使用率
      - DiskRunningOut      # 磁盘空间
      - TooHighActiveSeries # 活跃序列数
      - TooSlowQueries      # 查询延迟
      - TooManySlowInserts  # 写入延迟
      - TooManyErrors       # 错误率

  - infrastructure:
      - CPU > 80%          # CPU 使用率
      - 内存 > 85%         # 内存使用率
      - 磁盘 > 80%         # 磁盘使用率
      - fd > 50000         # 文件描述符数

16.2.4 备份规范

频率 保留 内容
每日 7 天 全量数据备份
每周 4 周 全量数据备份(独立存储)
每月 12 个月 归档备份(冷存储)

16.3 标签设计最佳实践

16.3.1 标签命名规范

# 标签命名规范
naming_convention:
  - 全小写,使用下划线分隔    # ✅ host_name / ❌ HostName
  - 语义清晰                  # ✅ region / ❌ r
  - 避免高基数                # ❌ user_id / ✅ user_bucket
  - 避免动态值                # ❌ request_id / ✅ request_path
  - 统一命名                  # ✅ job / ❌ service_name vs app

16.3.2 常见标签及其推荐值

标签 推荐值 基数 说明
job “api-server”, “web” 应用名
instance “host:port” 实例地址
env “prod”, “staging”, “dev” 极低 环境
region “cn-north”, “us-east” 极低 地域
host “web01”, “db02” 主机名
status “200”, “404”, “500” 状态码
method “GET”, “POST” 极低 HTTP 方法
path “/api/users” 请求路径

16.3.3 避免高基数标签

# ❌ 避免:高基数标签
http_requests_total{user_id="12345678"}  # 用户数可能几百万

# ✅ 正确:使用分桶或其他聚合方式
http_requests_total{user_bucket="12xx"}  # 只保留前 2 位
# 或
http_requests_total{endpoint="/api/users", status="200"}
# 用户维度放在日志/链路中,不在指标中

16.4 查询优化最佳实践

16.4.1 常见查询优化模式

# ❌ 不推荐:全量扫描
rate(http_requests_total[5m])

# ✅ 推荐:精确过滤
rate(http_requests_total{job="api-server", env="prod"}[5m])

# ❌ 不推荐:大时间窗口
avg_over_time(cpu_usage[7d])

# ✅ 推荐:使用 Recording Rule 预计算
# 预计算规则:
# record: job:cpu_usage:avg_7d
# expr: avg by (job) (avg_over_time(cpu_usage[7d]))
# 查询时:
job:cpu_usage:avg_7d

# ❌ 不推荐:嵌套聚合
topk(10, sum by (host) (rate(http_requests_total[5m])))

# ✅ 推荐:使用 Recording Rule 分步计算
# 步骤 1: 录制中间结果
# record: host:http_requests:rate5m
# expr: sum by (host) (rate(http_requests_total[5m]))
# 步骤 2: 查询
topk(10, host:http_requests:rate5m)

16.4.2 Grafana 仪表盘优化

dashboard_best_practices:
  - 使用变量(Variables):
    - $job: 允许用户选择 job
    - $host: 允许用户选择 host
    - $interval: 允许用户选择聚合间隔

  - 时间范围对齐:
    - 使用 $__rate_interval 代替固定 [5m]
    - 保证 rate() 的时间窗口 ≥ 2 × scrape_interval

  - 减少面板数据量:
    - 限制每个面板的最大序列数
    - 使用 topk/bottomk 限制显示数量
    - 使用 Recording Rule 预计算复杂表达式

16.4.3 Recording Rule 命名规范

命名格式:level:metric_name:aggregation

示例:
  job:http_request_duration_seconds:p99    # 按 job 聚合的 P99 延迟
  host:http_requests:rate5m               # 按 host 聚合的 5m 请求速率
  cluster:cpu_usage:avg                   # 按集群聚合的平均 CPU 使用率
  job:http_errors:ratio5m                 # 按 job 聚合的 5m 错误率

16.5 高可用架构最佳实践

16.5.1 架构选型决策树

你的数据规模和可用性要求?

├── 数据量 < 100 万序列,可用性要求一般
│   └── 单节点版 + 定期备份
│       ├── 简单部署
│       ├── 最低成本
│       └── 适合开发/测试/小规模生产
│
├── 数据量 100 万 - 1000 万,可用性要求高
│   └── 集群版 + 副本因子 2
│       ├── vminsert × 2
│       ├── vmselect × 2
│       ├── vmstorage × 3 (副本 2)
│       └── 适合中大规模生产
│
└── 数据量 > 1000 万,极高可用性要求
    └── 集群版 + 副本因子 3 + 多可用区
        ├── vminsert × 3+
        ├── vmselect × 3+
        ├── vmstorage × 5+ (副本 3)
        ├── 多可用区部署
        └── 适合大型企业生产

16.5.2 集群高可用配置

# vminsert HA 配置
vminsert \
    -storageNode=vmstorage1:8400,vmstorage2:8400,vmstorage3:8400 \
    -replicationFactor=2 \
    -dedup.minScrapeInterval=15s

# vmselect HA 配置
vmselect \
    -storageNode=vmstorage1:8401,vmstorage2:8401,vmstorage3:8401 \
    -dedup.minScrapeInterval=15s \
    -search.maxConcurrentRequests=16 \
    -cacheDataPath=/var/lib/vmselect/cache

16.5.3 多可用区部署

可用区 A                          可用区 B
┌──────────────┐                ┌──────────────┐
│ vminsert-1   │                │ vminsert-2   │
│ vmselect-1   │                │ vmselect-2   │
│ vmstorage-1  │◀──复制──▶│ vmstorage-2  │
│ vmstorage-3  │                │ vmstorage-4  │
└──────────────┘                └──────────────┘

每个可用区至少 2 个 vmstorage 节点
副本因子 = 2,确保每个副本在不同可用区

16.6 安全最佳实践

16.6.1 安全清单

# 项目 推荐配置
1 绑定地址 127.0.0.1:8428
2 反向代理 Nginx + TLS + Basic Auth
3 防火墙 只开放必要端口
4 认证 vmauth 或 Nginx Basic Auth
5 TLS 生产环境必须启用
6 最小权限 只读用户 / 写入用户分离
7 定期审计 检查访问日志
8 版本更新 定期升级到最新稳定版

16.6.2 网络安全配置

# Nginx 反向代理 + TLS + 认证
server {
    listen 443 ssl http2;
    server_name vm.example.com;

    ssl_certificate /etc/ssl/vm.crt;
    ssl_certificate_key /etc/ssl/vm.key;
    ssl_protocols TLSv1.2 TLSv1.3;

    # 写入端点 - 只允许内部 IP
    location /api/v1/write {
        allow 10.0.0.0/8;
        allow 172.16.0.0/12;
        deny all;
        proxy_pass http://127.0.0.1:8428;
    }

    # 查询端点 - Basic 认证
    location /api/v1/query {
        auth_basic "VictoriaMetrics";
        auth_basic_user_file /etc/nginx/.htpasswd;
        proxy_pass http://127.0.0.1:8428;
    }

    # VMUI - Basic 认证
    location /vmui/ {
        auth_basic "VictoriaMetrics";
        auth_basic_user_file /etc/nginx/.htpasswd;
        proxy_pass http://127.0.0.1:8428;
    }
}

16.7 持续优化

16.7.1 定期审查项目

频率 审查内容 工具/命令
每周 活跃序列数趋势 vm_active_timeseries
每周 磁盘使用趋势 vm_free_disk_space_bytes
每周 查询性能 Top Queries 页面
每月 标签基数 /api/v1/status/tsdb
每月 慢查询分析 vm_slow_queries_total
每月 资源使用率 Grafana 仪表盘
每季度 容量规划 序列增长趋势分析
每季度 保留策略 按业务需求调整
每半年 版本升级 评估新版本功能

16.7.2 成本优化

成本优化路径:

1. 数据压缩(已内置)
   └── VM 比 Prometheus 节省 7-10 倍存储成本

2. 降采样
   └── 老数据降低精度,减少存储

3. 按需保留
   └── 不同数据类型不同保留期

4. 标签优化
   └── 减少高基数标签,降低序列数

5. 采集频率优化
   └── 非关键指标 30s-60s 间隔

6. 架构优化
   └── 使用 vmagent 流式聚合

16.7.3 版本升级策略

版本升级流程:

1. 评估
   ├── 阅读 Release Notes
   ├── 检查 Breaking Changes
   └── 在测试环境验证

2. 备份
   ├── 创建数据快照
   └── 备份配置文件

3. 升级
   ├── 单节点:停止服务 → 替换二进制 → 启动
   └── 集群版:滚动升级(vmstorage → vminsert → vmselect)

4. 验证
   ├── 健康检查通过
   ├── 查询返回正常
   └── 写入速率正常

5. 监控
   ├── 升级后 24 小时密切监控
   └── 关注内存和 CPU 变化

16.8 生产部署检查清单

16.8.1 上线前检查

# 检查项 通过标准
1 版本选择 使用最新稳定版
2 资源配置 CPU/内存/磁盘按规划分配
3 存储类型 SSD (NVMe)
4 文件系统 XFS/ext4, noatime
5 fd 限制 >= 65536
6 数据目录 独立分区,权限正确
7 日志配置 JSON 格式,集中收集
8 认证配置 vmauth/Nginx 已配置
9 TLS 已启用
10 备份 自动化备份已配置
11 监控 自我监控 + 告警规则已配置
12 高可用 副本因子 >= 2 (集群版)
13 采集配置 vmagent/Prometheus 已配置
14 查询限制 maxConcurrentRequests 已设置
15 灾难恢复 恢复流程已演练

16.8.2 上线后监控

指标 告警阈值 说明
服务存活 up == 0 持续 1m 服务宕机
内存使用率 > 85% 持续 5m 可能 OOM
磁盘使用率 > 80% 需要扩容或清理
CPU 使用率 > 80% 持续 15m 需要优化或扩容
查询延迟 P99 > 10s 需要优化查询
写入延迟 vm_slow_inserts > 0 检查磁盘 I/O
活跃序列数 趋势性增长 容量规划
缓存命中率 < 70% 检查缓存配置

16.9 总结

VictoriaMetrics 核心价值

维度 价值
成本 存储成本降低 7-10 倍
性能 查询速度快 10-100 倍
运维 单二进制,无需外部依赖
兼容 完全兼容 Prometheus 生态
扩展 原生集群支持,水平扩展

关键成功因素

成功的 VM 部署 = 合理的容量规划
               + 正确的架构选型
               + 规范的标签设计
               + 完善的监控告警
               + 定期的优化审查

扩展阅读