Prometheus 2.0: новый TSDB и план миграции с 1.x без боли
Prometheus 2.0 выпущен стабильным: новый TSDB снижает потребление диска на 70%, но требует полного сброса данных. Строим план перехода без потери истории.
Выход Prometheus 2.0 со стабильным релизом нового движка TSDB - несовместимость формата данных с 1.x, радикальное снижение потребления диска и CPU
Prometheus 2.0 вышел стабильным в ноябре 2017-го, но мы не торопились - ждали когда пообтешется экосистема. Сейчас февраль, первые production-истории есть, и мы наконец разбираем что делать с нашими 1.x-инстансами. Спойлер: миграция требует полного сброса данных, и к этому надо готовиться заранее.
Что изменилось в движке
Главное в 2.0 - это не новые фичи PromQL, а полностью переписанный TSDB. В 1.x хранилище было основано на LevelDB с дополнительными индексами - ряд хорошо известных проблем: файловые дескрипторы заканчивались при большом количестве серий, retention работал не очень точно, а потребление диска при высокой кардинальности метрик было болезненным.
Новый TSDB Фабиана Райнарца (теперь он в команде Prometheus) написан с нуля. Ключевые отличия, которые видны на практике:
- Блочная организация данных. Данные хранятся в блоках по 2 часа, каждый блок - независимый набор файлов с собственным индексом. Compaction запускается в фоне и сжимает старые блоки. Удаление по retention - удаление целого блока, а не точечная операция.
- Потребление диска. На тестовом стенде с реальным трафиком одного клиентского стека - снижение примерно на 70% по сравнению с 1.x при той же глубине хранения. Это не маркетинговые цифры из слайдов, это реальное измерение на нашем стенде, хотя результат сильно зависит от профиля метрик.
- Потребление памяти тоже заметно ниже при высокой кардинальности - в 1.x каждая уникальная комбинация лейблов держала структуры в памяти постоянно, новый движок агрессивнее выгружает неактивные серии.
Главная засада: форматы несовместимы
Старый и новый TSDB хранят данные в принципиально разных форматах. Prometheus 2.0 не читает данные 1.x - и это не баг, а осознанное решение: совместимость тянула бы за собой весь легаси-код.
Официальный путь: Prometheus 2.0 умеет запускаться с флагом --storage.tsdb.path указывающим на пустую директорию, и параллельно можно поднять старый 1.x как remote_read источник через adapter. Проект prometheus/prometheus содержит cmd/promtool с командой tsdb migrate, но это не панацея - для больших объёмов всё равно долго.
Варианты которые мы рассматриваем для клиентских стеков под нашим управлением:
- Чистый старт. Принять потерю истории (если горизонт хранения небольшой - 15-30 дней), поднять 2.0 на новом хранилище, 1.x выключить. Самый простой путь.
- Параллельная работа. Оба инстанса скрейпят одни и те же таргеты какое-то время, Grafana смотрит на оба через Federation или через оба datasource. Когда история в 2.0 накопилась достаточно - 1.x выключить. Нагрузка на таргеты удваивается на период перехода.
- Remote read bridge. Настроить
remote_readв 2.0 на 1.x через storage adapter. Работает, но добавляет latency на исторические запросы и требует держать 1.x живым.
Для большинства наших клиентских стеков ответ: чистый старт. История мониторинга 15 дней назад - это хорошо иметь, но не критично. Критично чтобы новый Prometheus поднялся стабильно и начал собирать.
Несовместимости в конфигурации
Помимо данных, 2.0 принёс ряд изменений в конфиг:
target_label: __address__в relabel_configs теперь обрабатывается иначе в нескольких edge-кейсах. Если у вас хитрые relabel-правила - проверяйте.- Флаги демона поменяли синтаксис:
-storage.local.*исчезли, на их место пришли-storage.tsdb.*. Старые флаги не работают - при старте будет ошибка, не молчаливое игнорирование. alertmanager_configполучил полеapi_version- по умолчанию v1, но если у вас Alertmanager 0.12+, стоит переключаться на v2 API.
Мы прогнали конфиги через promtool check config в среде 2.0 перед тем как трогать production. Это обязательный шаг - сэкономит нервы.
Как выглядит план перехода
На managed-инфраструктуре мы идём по следующему алгоритму:
- Поднять Prometheus 2.0 рядом со старым, на отдельном порту и отдельном хранилище.
- Настроить конфиг 2.0 по образцу текущего 1.x, прогнать через
promtool check config. - Переключить часть таргетов (сначала некритичные) на скрейп обоими инстансами.
- Grafana: добавить datasource 2.0, проверить дашборды на его данных. Некоторые функции PromQL чуть изменились в поведении на пограничных случаях - лучше проверить заранее.
- Когда всё устраивает - переключить alerting-правила на 2.0, выключить 1.x.
Параллельный скрейп двух инстансов держать не дольше двух недель: лишняя нагрузка на таргеты и двойной расход диска.
Что с Alertmanager
Alertmanager не требует миграции данных - его состояние (active alerts, silences) хранится отдельно и 2.0 с ним работает без проблем. Но мы используем момент чтобы и его обновить до актуальной версии 0.12, пока всё равно трогаем стек.
Где стоим
На одном стенде 2.0 уже работает неделю, данные накапливаются. По потреблению диска - подтверждаем существенное снижение, цифры сойдутся через пару недель когда накопится статистика на полный retention-период. По production-переходу клиентских стеков - начинаем с наименее критичных окружений на следующей неделе.
Новый TSDB выглядит как серьёзный технический прогресс, но именно «выглядит» - пока у нас нет нескольких месяцев production под нагрузкой, это ещё проверяемая гипотеза, а не факт.