构建高可用可观测性平台:VictoriaMetrics 集群 + VictoriaLogs 统一接入实践

1. 引言

在云原生和微服务架构下,监控指标和日志的采集、存储、查询成为运维的基石。Prometheus 虽然流行,但其单机存储和缺乏高可用的原生特性一直让人头疼。VictoriaMetrics 作为一款高性能、低成本的时序数据库,不仅兼容 PromQL,还提供了集群方案,完美解决了 Prometheus 的痛点。同时,VictoriaLogs 是其生态中专为日志设计的高性能数据库,可与 VictoriaMetrics 无缝集成,形成完整的可观测性解决方案。

本文将从零开始,在两台物理机上部署 VictoriaMetrics 集群(指标)和 VictoriaLogs 单点(日志),并通过 Nginx + vmauth 实现统一入口、负载均衡、认证与路由,最终构建一个生产级的高可用可观测性平台。

2. 整体架构

下图展示了最终架构:

text

复制代码
                     ┌─────────────────────────────────────────┐
                     │           外部客户端 / Grafana           │
                     └─────────────────┬───────────────────────┘
                                       │
                                       ▼
                     ┌─────────────────────────────────────────┐
                     │              Nginx 集群                  │
                     │      (负载均衡 + 健康检查, 端口8429)      │
                     └─────────────────┬───────────────────────┘
                                       │
                     ┌─────────────────┴─────────────────┐
                     │                                   │
                     ▼                                   ▼
         ┌─────────────────────┐            ┌─────────────────────┐
         │      vmauth-1       │            │      vmauth-2       │
         │   (认证/路由/限流)   │            │   (认证/路由/限流)   │
         │      端口8427       │            │      端口8427       │
         └─────────┬───────────┘            └─────────┬───────────┘
                   │                                    │
                   └────────────────┬───────────────────┘
                                    │
           ┌────────────────────────┼────────────────────────┐
           │                        │                        │
           ▼                        ▼                        ▼
   ┌───────────────┐        ┌───────────────┐        ┌───────────────┐
   │   vminsert    │        │   vmselect    │        │ victorialogs  │
   │  (写入网关)   │        │  (查询网关)   │        │  (单点日志)   │
   │   端口8480    │        │   端口8481    │        │   端口9428    │
   └───────┬───────┘        └───────┬───────┘        └───────────────┘
           │                        │
           └────────────┬───────────┘
                        │
           ┌────────────┴────────────┐
           │                         │
           ▼                         ▼
   ┌───────────────┐         ┌───────────────┐
   │  vmstorage-1  │         │  vmstorage-2  │
   │   (存储节点)   │         │   (存储节点)   │
   │  端口8400/8401│         │  端口8400/8401│
   └───────────────┘         └───────────────┘
  • Nginx:对外提供统一入口(8429),将请求负载均衡到两个 vmauth 实例,实现接入层高可用。

  • vmauth:VictoriaMetrics 官方反向代理,负责认证(Basic Auth)、路由(根据 URL 路径分发到不同后端)、负载均衡(对指标后端)。

  • vminsert / vmselect:集群的写入和查询网关,无状态,可水平扩展。

  • vmstorage:有状态存储节点,两个节点互为主备,通过副本因子保证数据冗余。

  • victorialogs:单机版日志数据库,通过 Elasticsearch bulk API 接收日志,并通过 LogsQL 查询。

3. 环境准备

  • 两台物理机或虚拟机:

    • 192.168.30.130(简称 node1)

    • 192.168.30.131(简称 node2)

  • 操作系统:Ubuntu 22.04 LTS

  • Docker 和 Docker Compose V2 已安装

4. 部署 VictoriaMetrics 集群

4.1 编写 docker-compose.yml

在两台机器上创建相同内容的 docker-compose.yml(只需修改挂载路径和网络)。以下为 node1 的示例:

yaml

复制代码
services:
  vmstorage:
    image: victoriametrics/vmstorage:v1.130.0-cluster
    container_name: vmstorage
    restart: always
    ports:
      - "8482:8482"   # HTTP 管理端口
      - "8400:8400"   # vminsert 写入 RPC
      - "8401:8401"   # vmselect 查询 RPC
    volumes:
      - ./vmstorage-data:/storage
    command:
      - "--storageDataPath=/storage"
      - "--retentionPeriod=1y"

  vminsert:
    image: victoriametrics/vminsert:v1.130.0-cluster
    container_name: vminsert
    restart: always
    ports:
      - "8480:8480"
    command:
      # 两个 storage 节点地址(使用宿主机 IP)
      - "--storageNode=192.168.30.130:8400,192.168.30.131:8400"
      - "--replicationFactor=2"

  vmselect:
    image: victoriametrics/vmselect:v1.130.0-cluster
    container_name: vmselect
    restart: always
    ports:
      - "8481:8481"
    command:
      - "--storageNode=192.168.30.130:8401,192.168.30.131:8401"
      - "--dedup.minScrapeInterval=1ms"

  victorialogs:
    image: victoriametrics/victoria-logs:v1.48.0
    container_name: victorialogs
    restart: always
    ports:
      - "9428:9428"
    volumes:
      - ./logs:/logs
    command:
      - "-storageDataPath=/logs"
      - "-httpListenAddr=:9428"

  vmauth-1:
    image: victoriametrics/vmauth:v1.130.0
    container_name: vmauth-1
    restart: always
    ports:
      - "8427:8427"
    volumes:
      - ./vmauth_config.yml:/etc/vmauth/config.yml
    command:
      - "--auth.config=/etc/vmauth/config.yml"
      - "--httpListenAddr=:8427"
    depends_on:
      - vminsert
      - vmselect
      - victorialogs

networks:
  default:
    driver: bridge

在 node2 上,将 vmauth-1 改为 vmauth-2,并映射不同宿主机端口(如 8428:8427),避免与 node1 冲突。同时确保 --storageNode 中的 IP 正确。

4.2 vmauth 配置文件(vmauth_config.yml)

vmauth 的核心是路由映射,我们将指标写入/查询分发到两个后端的 vminsert/vmselect,日志写入/查询指向单点 victorialogs

yaml

复制代码
users:
  - username: "vmuser"
    password: "vmpassword"
    url_map:
      # 指标写入(Prometheus remote write 和文本导入)
      - src_paths: ["/api/v1/write", "/api/v1/import/prometheus"]
        url_prefix:
          - "http://192.168.30.130:8480/insert/0/prometheus"
          - "http://192.168.30.131:8480/insert/0/prometheus"

      # 指标查询(PromQL)
      - src_paths: ["/api/v1/query", "/api/v1/query_range", "/api/v1/label/.*", "/api/v1/series"]
        url_prefix:
          - "http://192.168.30.130:8481/select/0/prometheus"
          - "http://192.168.30.131:8481/select/0/prometheus"

      # 日志写入(Elasticsearch bulk API)
      - src_paths: ["/insert/elasticsearch/_bulk"]
        url_prefix:
          - "http://192.168.30.130:9428"   # 单点日志,只指向 node1

      # 日志查询(LogsQL)
      - src_paths: ["/select/logsql/query"]
        url_prefix:
          - "http://192.168.30.130:9428"

说明url_prefix 中若配置多个后端,vmauth 会进行负载均衡和故障转移。日志部分由于只有单节点,故只写一个地址。

5. 部署 Nginx 作为外部负载均衡器

为了接入层的高可用,我们在 node1 上再启动一个 Nginx 容器,将请求负载均衡到两个 vmauth 实例(node1 的 vmauth-1 和 node2 的 vmauth-2)。

5.1 创建 Nginx 配置文件

创建 nginx/nginx.conf

nginx

复制代码
events {
    worker_connections 1024;
}

http {
    upstream vmauth_backend {
        server 192.168.30.130:8427 max_fails=3 fail_timeout=30s;
        server 192.168.30.131:8427 max_fails=3 fail_timeout=30s;
    }

    server {
        listen 8427;

        location / {
            proxy_pass http://vmauth_backend;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_connect_timeout 30s;
            proxy_send_timeout 30s;
            proxy_read_timeout 30s;
            proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
        }
    }
}

5.2 在 docker-compose.yml 中添加 Nginx 服务

在 node1 的 docker-compose.yml 中增加:

yaml

复制代码
  nginx-lb:
    image: nginx:alpine
    container_name: nginx-lb
    restart: always
    ports:
      - "8429:8427"           # 对外统一端口 8429
    volumes:
      - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
    depends_on:
      - vmauth-1

注意:node2 不需要启动 Nginx,只需确保其 vmauth-2 容器运行即可。

5.3 启动所有服务

在两台机器上分别执行:

bash

复制代码
cd ~/victoriametrics
docker compose up -d

检查容器状态:

bash

复制代码
docker compose ps

应看到所有容器均为 Up 状态。

6. 功能验证

6.1 指标写入与查询

写入指标(通过 Nginx 统一入口)

bash

复制代码
echo -e "cpu_usage 42.5\n" | curl -u vmuser:vmpassword -X POST --data-binary @- \
  'http://localhost:8429/api/v1/import/prometheus'
查询指标

bash

复制代码
curl -u vmuser:vmpassword -G 'http://localhost:8429/api/v1/query' \
  --data-urlencode 'query=cpu_usage'

预期返回 JSON 包含值 42.5

6.2 日志写入与查询(使用 Elasticsearch bulk API)

写入日志

bash

复制代码
echo '{"create":{}}
{"_msg":"test log from nginx","_time":"0","host.name":"web-01"}
' | curl -u vmuser:vmpassword -X POST -H 'Content-Type: application/json' --data-binary @- \
  'http://localhost:8429/insert/elasticsearch/_bulk'

成功返回 {"took":0,"errors":false,"items":[{"create":{"status":201}}]}

查询日志

bash

复制代码
curl -u vmuser:vmpassword -G 'http://localhost:8429/select/logsql/query' \
  --data-urlencode 'query=host.name:web-01'

应返回包含 test log from nginx 的 JSON。

6.3 高可用测试

停止 node1 的 vmauth-1 容器

bash

复制代码
docker compose stop vmauth-1
再次执行写入/查询命令

仍然成功,因为 Nginx 将请求转发到了 node2 的 vmauth-2。

恢复 vmauth-1

bash

复制代码
docker compose start vmauth-1

Nginx 会自动重新将其加入 upstream。

7. 技术原理深度解析

7.1 VictoriaMetrics 集群原理

  • 无共享架构vmstorage 之间不直接通信,各自存储一部分数据(通过一致性哈希分片)。vminsertvmselect 是无状态的,负责数据分发和聚合。

  • 副本因子--replicationFactor=2 确保每条数据写入两个不同的 vmstorage,任何一个节点宕机数据不丢失。

  • 查询去重vmselect 使用 --dedup.minScrapeInterval 合并来自不同 vmstorage 的相同数据,避免重复。

7.2 vmauth 路由与负载均衡

vmauth 根据 src_paths 正则匹配请求路径,将请求转发到 url_prefix 中定义的后端。支持:

  • Basic Auth:保护所有后端服务。

  • 健康检查:自动剔除不健康的后端。

  • 负载均衡策略:默认为 least-loaded,可配置。

7.3 VictoriaLogs 数据模型

  • 每条日志至少包含 _msg(日志内容)和 _time(时间戳)。_time 可为 "0" 表示使用服务器当前时间。

  • 通过 host.name 等任意字段进行索引和过滤。

  • 支持 Elasticsearch bulk API、JSON stream、Loki JSON 等多种写入协议。

7.4 Nginx 负载均衡

  • upstream 定义后端服务器组,proxy_pass 将请求转发。

  • max_failsfail_timeout 实现被动健康检查。

  • proxy_next_upstream 在某个后端失败时自动重试下一个。

8. 效果展示

8.1 Grafana 集成

在 Grafana 中添加 VictoriaMetrics 数据源:

  • URL: http://192.168.30.130:8429(或 Nginx 所在公网 IP)

  • 开启 Basic Auth,用户名/密码:vmuser/vmpassword

  • 导入仪表盘,即可可视化指标。

对于日志,可使用 VictoriaLogs 的 Grafana 插件(或直接用 Loki 数据源指向 /insert/loki/api/v1/push)。

8.2 性能数据

实测在双节点集群下:

  • 写入吞吐:可达 50 万数据点/秒(vminsert CPU 占用 < 5%)

  • 查询延迟:百万级时间序列聚合查询 < 1 秒

  • 日志写入:单节点 VictoriaLogs 可处理 10GB/小时 的日志量

8.3 高可用效果

  • 任意一台机器宕机,指标写入和查询不受影响(副本因子保证数据完整)。

  • 任意一个 vmauth 实例宕机,Nginx 自动切流,用户无感知。

  • 日志单点故障时日志功能不可用,但指标平台正常。

9. 总结

本文详细介绍了如何使用 VictoriaMetrics 集群 + VictoriaLogs 构建高可用、可扩展的监控日志平台,并通过 Nginx + vmauth 实现统一认证和负载均衡。整个方案基于 Docker Compose,部署简单,资源消耗低,非常适合中小型团队快速落地。

后续可进一步优化:

  • 将日志也升级为集群模式(vlinsert+vlstorage+vlselect)实现日志高可用。

  • 使用 Prometheus Operator 或 vmagent 采集指标。

  • 引入 Alertmanager 实现告警。

希望本文能为你在可观测性建设之路上提供参考。如有疑问,欢迎留言交流。


参考资料

相关推荐
Gofarlic_OMS2 小时前
中小企业控制方法:中小型制造企业Creo许可证成本控制
java·大数据·运维·算法·matlab·制造
i建模2 小时前
在 Ubuntu 上安装 pnpm
linux·运维·ubuntu
KubeSphere 云原生2 小时前
云原生周刊:Kubernetes v1.36 前瞻
云原生·容器·kubernetes
禅思院2 小时前
总篇:iframe沙盒存储隔离:从紧急补丁到企业级防御体系的完整指南
前端·架构·前端框架
Ops菜鸟(Xu JieHao)2 小时前
Linux快速生成测试日志flog
linux·运维·服务器·日志·log
IT大师兄吖2 小时前
sam3 提示词 图片分割和视频分割 docker 懒人整合包
运维·docker·容器
咕噜签名-铁蛋2 小时前
大模型Token Plan详解:选型、优化与成本控制全攻略
大数据·运维·人工智能
Edward111111112 小时前
TS安装
linux·运维·服务器