ADG Оставить заявку
Блог DevOps 5 мин чтения

Thanos и remote_write: когда 90 дней метрик Prometheus перестают помещаться

Разобрали Thanos как способ долгосрочного хранения метрик Prometheus через remote_write в object storage - и поняли, что это другая архитектура, не просто плагин.

Контекст момента

Thanos - проект для долгосрочного хранения метрик Prometheus, анонсированный сообществом как open-source решение поверх object storage

Prometheus справляется с оперативным мониторингом очень хорошо. Это не комплимент из вежливости - он реально работает: scrape, TSDB, alerting, PromQL. Но у него есть физическое ограничение, которое рано или поздно становится разговором с заказчиком: локальный диск. Данные за 90 дней, несколько тысяч метрик, несколько инстансов - это быстро превращается в дискуссию про NVMe или в решение о том, что старше двух недель нам не нужно. Ни то ни другое нас не устраивало.

Когда в прошлом году сообщество анонсировало Thanos как open-source проект для долгосрочного хранения поверх object storage, мы решили смотреть внимательно.

Что за зверь Thanos

Thanos - это не fork Prometheus и не замена ему. Это несколько компонентов, которые встраиваются рядом и берут на себя то, что Prometheus не делает: репликацию данных в object storage, глобальный query layer поверх нескольких инстансов, и downsampling для длинных временных горизонтов.

Архитектура примерно такая:

graph LR
    P1[Prometheus 1] -->|remote_write| SW1[Thanos Sidecar 1]
    P2[Prometheus 2] -->|remote_write| SW2[Thanos Sidecar 2]
    SW1 -->|upload TSDB blocks| S3[(Object Storage)]
    SW2 -->|upload TSDB blocks| S3
    S3 --> STO[Thanos Store]
    SW1 --> QR[Thanos Querier]
    SW2 --> QR
    STO --> QR
    QR -->|PromQL| GR[Grafana]

Thanos Sidecar запускается рядом с каждым Prometheus-ом. Он делает две вещи: открывает gRPC endpoint для Thanos Querier (чтобы тот мог ходить за свежими данными напрямую в TSDB), и периодически заливает закрытые TSDB-блоки в object storage. Thanos Store читает из object storage и отвечает на запросы Querier по старым данным. Querier склеивает всё в единый PromQL endpoint - Grafana смотрит на него как на обычный Prometheus.

Важная деталь: remote_write здесь используется не для передачи данных в object storage напрямую. Thanos Sidecar работает с TSDB-блоками - он читает файлы, которые Prometheus пишет локально, и загружает их когда блок закрывается (обычно каждые 2 часа). Remote_write - это другой путь, который Prometheus поддерживает параллельно и который можно направить куда угодно. В нашем случае мы использовали оба подхода: Sidecar для основного хранения, remote_write для дублирования в тестовый Cortex для сравнения.

Как разворачивали

Тестировали на managed-проекте с несколькими Prometheus-инстансами в Kubernetes. Задача: один из инстансов уже собирал метрики несколько месяцев, хотелось не потерять историю и добавить возможность смотреть на данные за полгода.

Thanos Sidecar добавляется как дополнительный контейнер в StatefulSet с Prometheus. Конфигурация минимальная - нужно дать ему S3-совместимый endpoint и credentials, указать директорию с данными Prometheus. Мы использовали Minio как S3-совместимое хранилище (в кластере уже стоял для других нужд), но в production имеет смысл смотреть на облачный S3 или аналог - хранить метрики там же где сами серверы не всегда правильно.

Thanos Querier разворачивается отдельно и получает список sidecar endpoint-ов через --store параметры. Для него нужен Ingress или NodePort - это новый endpoint для Grafana.

Thanos Store - ещё один Deployment, который умеет читать объекты из S3 и отдавать их в формате, понятном Querier. Ему нужен persistent volume для кеша (иначе при каждом запросе он будет тянуть данные из S3 заново, что медленно).

Что сразу бросилось в глаза: Querier умеет дедуплицировать метрики от нескольких Prometheus-инстансов, если они собирают одно и то же. Это решает проблему HA - можно запустить два Prometheus-а с одинаковыми scrape configs, и Thanos Querier покажет единый ряд без дублей. Мы не тестировали это всерьёз, но в демо-режиме работает правильно.

Где споткнулись

Версионирование компонентов. Thanos - молодой проект, версии sidecar, querier и store должны быть совместимы. Мы поставили разные версии из-за невнимательности - gRPC контракт не совпал, Querier не мог достучаться до Sidecar. Ошибка диагностировалась не очевидно: в логах было что-то про несовместимые protobuf версии, а не прямая надпись «версии не совпадают».

Labels deduplication. Querier дедуплицирует по label replica. Это нужно явно добавлять в external_labels Prometheus-а. Если не добавить - дедупликация не работает, получаешь задвоенные ряды в Grafana, начинаешь думать что сломал конфигурацию, хотя это просто отсутствующий label.

Downsampling не бесплатный. Thanos Compactor - отдельный компонент, который делает downsampling и compaction. Без него объекты в S3 копятся как есть: каждые 2 часа новый блок. Когда смотришь на год данных через Querier без compaction - это медленно, потому что Store честно читает все блоки по одному. Compactor мы поставили, но надо понимать что он должен быть только один - если запустить несколько Compactor-ов на одни данные, они будут конфликтовать.

Где сейчас

Thanos пока работает на одном проекте как пилот. Данные за несколько месяцев уходят в Minio, Grafana смотрит на Querier без изменений в дашбордах - это приятно, не пришлось переписывать ни одного запроса. Исторические данные из S3 отвечают медленнее чем из локального TSDB, но для аналитики за квартал это приемлемо.

Compactor запущен с суточным расписанием. Downsampling на 5m и 1h включен - старые данные из S3 возвращаются в Grafana быстрее.

Главный вывод пока: это не «поставил и забыл». Thanos требует понимания всех своих компонентов и того, как они взаимодействуют. Но если задача - хранить метрики дольше нескольких недель без покупки очень большого диска, альтернативных подходов почти нет.

Контакт

Нужна такая же инженерная работа?

Опишите задачу и контекст. Ответим в течение рабочего дня, при необходимости подпишем NDA.