В прошлом году 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 упирается в ресурсы или ретеншн — попробуйте, переезд занимает вечер.