В прошлом году Prometheus на одной из моих сборочных нод начал упираться в RAM: 3 ГБ под TSDB, периодические рестарты по OOM, retention пришлось ужать до 30 дней. Я долго откладывал миграцию на VictoriaMetrics, потому что «работает же», но в итоге решился, и потратил один вечер. С тех пор та же нода держит 90 дней метрик на 600 МБ RAM. Расскажу, как и почему.

Чем VictoriaMetrics отличается от Prometheus

Если коротко — это переписанный с нуля time-series storage, совместимый с PromQL и Prometheus remote_write API. Разработан в Go, разработчики — выходцы из Cloudflare. Основные плюсы по сравнению с Prometheus 2.x:

  • В 3-7 раз меньше памяти на той же кардинальности
  • Сжатие на диске лучше в 3-10 раз (зависит от данных)
  • Запросы по большим диапазонам быстрее
  • Кластеризация (платная enterprise или free open-source variant)

Минусы:

  • Не родной alertmanager-API (но есть vmalert, который умеет то же самое)
  • Чуть другой подход к downsampling (в open-source версии downsampling нет, только в enterprise)
  • Поведение в edge-кейсах PromQL может слегка отличаться (stale markers, например)

Архитектура переезда

Старая схема:

node_exporter -> Prometheus -> Grafana
                    |
                    +-> alertmanager

Новая:

node_exporter -> vmagent -> VictoriaMetrics -> Grafana
                                ^
                                |
                              vmalert -> alertmanager

vmagent — это лёгкий агент для сбора и форвардинга метрик. По функциям — замена Prometheus в scrape-режиме. Полезно тем, что его можно держать на каждой ноде локально, а централизованную VictoriaMetrics — где-то в одном месте.

Docker compose

services:
  victoriametrics:
    image: victoriametrics/victoria-metrics:v1.106.1
    container_name: vm
    restart: unless-stopped
    volumes:
      - vm-data:/storage
    command:
      - '--storageDataPath=/storage'
      - '--retentionPeriod=90d'
      - '--httpListenAddr=:8428'
      - '--memory.allowedPercent=60'
    ports:
      - "127.0.0.1:8428:8428"
    mem_limit: 1g

  vmagent:
    image: victoriametrics/vmagent:v1.106.1
    container_name: vmagent
    restart: unless-stopped
    volumes:
      - ./vmagent.yml:/etc/vmagent/prometheus.yml:ro
      - vmagent-data:/vmagent-data
    command:
      - '--promscrape.config=/etc/vmagent/prometheus.yml'
      - '--remoteWrite.url=http://victoriametrics:8428/api/v1/write'
      - '--remoteWrite.tmpDataPath=/vmagent-data'
    mem_limit: 256m

  vmalert:
    image: victoriametrics/vmalert:v1.106.1
    container_name: vmalert
    restart: unless-stopped
    volumes:
      - ./rules:/etc/vmalert/rules:ro
    command:
      - '--datasource.url=http://victoriametrics:8428'
      - '--notifier.url=http://alertmanager:9093'
      - '--remoteWrite.url=http://victoriametrics:8428'
      - '--rule=/etc/vmalert/rules/*.yml'
    mem_limit: 128m

volumes:
  vm-data:
  vmagent-data:

--memory.allowedPercent=60 — это лимит, выше которого VictoriaMetrics начнёт жертвовать кэшем ради новых вставок. На контейнере с mem_limit: 1g это значит, что под кэш отведено 600 МБ.

Конфиг vmagent

Формат — точно такой же, как у Prometheus. Можно тупо взять prometheus.yml и положить как vmagent.yml:

global:
  scrape_interval: 30s
  external_labels:
    site: lab1

scrape_configs:
  - job_name: 'node'
    static_configs:
      - targets:
          - 10.8.0.2:9100
          - 10.8.0.3:9100
          - 10.8.0.4:9100

  - job_name: 'nginx'
    static_configs:
      - targets:
          - 10.8.0.2:9113

vmagent сам отправит scraped-метрики через remote_write в VictoriaMetrics. Если связь с VM пропадёт — он буферизует на диск в --remoteWrite.tmpDataPath (до 1 ГБ по дефолту).

Миграция данных

Если хотите перетащить исторические данные из Prometheus — есть vmctl:

docker run --rm -it \
  -v /var/lib/prometheus:/prom:ro \
  victoriametrics/vmctl:v1.106.1 \
  prometheus \
  --prom-snapshot=/prom/snapshots/20260120 \
  --vm-addr=http://10.0.0.5:8428

Сначала на Prometheus делается снапшот:

curl -XPOST http://localhost:9090/api/v1/admin/tsdb/snapshot

Потом снапшот скармливается vmctl, и он перельёт данные. У меня 2 ГБ Prometheus-данных переехали в 280 МБ VictoriaMetrics за 20 минут. Сжатие — 7x.

Grafana datasource

В Grafana добавляется как обычный Prometheus datasource:

Type: Prometheus
URL: http://victoriametrics:8428

Все существующие дашборды работают. Я не правил ничего.

Что заметил после переезда

RAM на ноде с метриками 14 нод × 100 метрик:

  • Prometheus 2.55: 3.2 ГБ steady, 4.5 ГБ при reload
  • VictoriaMetrics 1.106: 600 МБ steady, 800 МБ при reload

Disk:

  • Prometheus: 12 ГБ за 30 дней retention
  • VictoriaMetrics: 4.3 ГБ за 90 дней retention

CPU при запросах из Grafana:

  • Prometheus на range-запрос за 30 дней: 18% CPU на 4 секунды
  • VictoriaMetrics на range-запрос за 30 дней: 4% CPU на 1.2 секунды

Особенно заметна разница на больших range — Prometheus упирается в чтение блоков с диска, VictoriaMetrics это делает быстрее.

Грабли

Отсутствие downsampling в open-source

Если хочется хранить данные за год, но с уменьшенным разрешением (например, 1 час вместо 30 секунд) — в open-source VictoriaMetrics этого нет. Либо платная enterprise, либо ручной recording rule, который агрегирует метрики и пишет в отдельные серии.

vmalert и rule-evaluation

vmalert запускает PromQL-rule’ы и пишет результаты обратно в VictoriaMetrics. Это удобно, но если rule тяжёлый и часто evaluated — он съест CPU как на самом VM, так и на vmalert. Не злоупотребляйте.

Stale markers

В Prometheus, когда таргет пропадает, метрика помечается «stale» через 5 минут. В VictoriaMetrics это работает чуть иначе — staleness считается по -search.lookbackDelta. По дефолту 5 минут, но если у вас редкие метрики (раз в 10 минут) — могут быть провалы в графиках. Решается опцией --search.lookbackDelta=15m или повышением частоты scrape.

Cardinality

VictoriaMetrics с высокой кардинальностью справляется лучше, чем Prometheus, но не бесконечно. Если у вас миллионы уникальных серий — смотрите в сторону vmagent --remoteWrite.maxRowsPerBlock и кардинальной фильтрации на уровне scrape_configs.

Итог

VictoriaMetrics — это апгрейд Prometheus, который ничего не ломает. Совместим по PromQL, по remote_write, по экосистеме. Экономит память в разы, диск — на порядок. Минусов мало, и они касаются специфичных кейсов. Если у вас Prometheus упирается в ресурсы или ретеншн — попробуйте, переезд занимает вечер.