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

Prometheus 1.7 в продакшне: тюнинг retention, compaction и federation для нескольких площадок

Полгода Prometheus в проде - разбираем retention, compaction, remote_write в InfluxDB и federation-топологию для мониторинга нескольких площадок.

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

Prometheus 1.7 (июнь 2017) с улучшенным storage и federation

В феврале мы описывали первый продакшн-запуск Prometheus 1.5. С тех пор прошло четыре месяца, Prometheus обновился до 1.7, и у нас накопился список вещей которые в тестовой среде незаметны, а в проде начинают давить через пару недель работы. Плюс появились клиенты с несколькими площадками, и нужна была federation-топология. Рассказываем что тюнили и к чему пришли.

Где жало первые недели

Дефолтный Prometheus работает с параметрами для «потыкать руками», а не для production-нагрузки. Первое что прилетело - диск.

На одном из managed-проектов с четырьмя хостами и парой десятков контейнеров Prometheus за три недели набрал под 30 ГБ на диске. При дефолтном retention в 15 дней это означало около 2 ГБ в сутки - больше чем ожидали при планировании объёма. Начали разбираться.

Первое - chunks_directory растёт быстро при scrape_interval 15s. Каждые 15 секунд по нескольким тысячам временных рядов - это значительный объём сырых данных до compaction. Подняли interval до 30 секунд там где точность в 15 секунд не критична, и объём сразу упал вдвое.

Второе - retention надо выставлять явно. -storage.local.retention по умолчанию 360h (15 дней), но компания забыла указать его явно в unit-файле, и когда systemd-unit переписывали - параметр потерялся. Prometheus молча переключился на дефолт. Теперь все параметры storage идут в явном виде в конфиге запуска, ничего не оставляем «как есть».

Третье - compaction работает, но не сразу. Prometheus 1.7 делает compaction фоново, и свежеинсталлированный экземпляр первые сутки-двое выглядит будто жрёт диск неадекватно. Это нормально: chunks ещё не сложены в blocks. После первого полного цикла compaction размер резко падает. Без понимания этого поведения первый рефлекс - «что-то сломалось, надо перезапускать», что только мешает.

remote_write в InfluxDB: зачем и как

У нескольких клиентов требование хранить метрики дольше месяца - для capacity planning и для SLA-отчётности. Prometheus с 30-дневным retention на это не рассчитан: диск растёт линейно, и за год это будет неуправляемо.

Решение - remote_write через Telegraf в InfluxDB, который умеет downsampling и хранит агрегированные данные долго. Telegraf принимает remote_write по HTTP и пишет в InfluxDB через line protocol. Конфиг в Prometheus 1.7 простой:

remote_write:
  - url: "http://telegraf:9999/receive"
    write_relabel_configs:
      - source_labels: [__name__]
        regex: "node_.*|container_.*"
        action: keep

Пишем не всё, только системные метрики и контейнерные. Метрики самого Prometheus, Alertmanager и временные сервисные метрики в долгосрочное хранилище не льём - там нет смысла.

Главная засада с remote_write которую словили: если InfluxDB недоступен, Prometheus буферизует данные в памяти и на диске, но буфер ограничен. При длительном падении InfluxDB получаем «дыру» в долгосрочных данных без каких-либо алертов на эту ситуацию. Добавили алерт на prometheus_remote_storage_failed_samples_total - если счётчик растёт, надо разбираться.

В InfluxDB настроили два Retention Policy: один на 7 дней с полной детализацией (1 минута), второй на 365 дней с downsampling через Continuous Queries до 5-минутных агрегатов. Grafana умеет переключаться между ними по выбранному диапазону времени через разные datasource.

Federation для нескольких площадок

Когда у клиента два датацентра или продакшн-сеть плюс отдельный DMZ, встаёт вопрос как мониторить всё это из одного места. Prometheus federation - механизм где один «центральный» Prometheus scrape-ит /federate endpoint от «локальных» Prometheus-ов, получая нужные метрики.

Схема которую используем:

Площадка A                    Площадка B
Prometheus-A :9090            Prometheus-B :9090
  node_exporter               node_exporter
  cAdvisor                    cAdvisor
       |                            |
       |     federation scrape      |
       +----------+   +-------------+
                  |   |
           Prometheus-central
              (на нашей стороне)
                  |
             Alertmanager
             Grafana

Центральный Prometheus не scrape-ит конечные цели напрямую - только /federate эндпоинт на каждом локальном. Это означает что при недоступности площадки A, центральный Prometheus теряет её метрики, но метрики площадки B продолжают приходить нормально.

Конфиг federation scrape в центральном Prometheus:

scrape_configs:
  - job_name: 'federate-site-a'
    scrape_interval: 30s
    honor_labels: true
    metrics_path: '/federate'
    params:
      'match[]':
        - '{job=~"node-exporter|cadvisor"}'
        - 'up'
    static_configs:
      - targets: ['prometheus-a.site-a.internal:9090']
        labels:
          site: 'site-a'

honor_labels: true - обязательный параметр. Без него центральный Prometheus перезапишет labels из локального своими значениями, и вы потеряете instance метки оригинальных целей.

Что важно понимать про federation: это не репликация и не failover. Если локальный Prometheus перезапустился и потерял данные за последний час, центральный тоже не будет знать об этом часе. Federation - это агрегация для высокоуровневого мониторинга, а не резервное копирование метрик.

На практике разделили что живёт где: детальные метрики (CPU по контейнерам, RAM, диск) - только на локальных Prometheus-ах с 30-дневным retention. В центральном - агрегированные метрики уровня «площадка», SLA-метрики и up статусы всех сервисов. Grafana смотрит на центральный для overview-дашбордов и на локальные для детального дебага.

Мелкие вещи которые заняли время

Несколько наблюдений которые не тянут на раздел, но реально отняли время на отладку.

-storage.local.memory-chunks и OOM. При большом числе временных рядов дефолтное значение приводит к нехватке памяти. Выставляем явно исходя из доступной RAM: примерно по 3072 чанка на каждый ГБ памяти выделенной Prometheus. Не точная формула, но рабочая отправная точка.

Alertmanager и federation. Алерты должны приходить только из одного Alertmanager, даже если у вас несколько Prometheus-ов. Иначе получаете дублирующиеся уведомления при любом алерте. Конфигурируем все Prometheus-ы (и локальные, и центральный) на один Alertmanager.

external_labels в конфиге. Добавляем в каждый локальный Prometheus метки site и env через global.external_labels. Это позволяет в Alertmanager и Grafana сразу видеть откуда пришёл алерт без разбора по IP адресам.

Prometheus 1.7 - рабочий инструмент, который требует осознанной настройки под реальную нагрузку. Дефолты покрывают только демо-стенд.

Контакт

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

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