Введение в Prometheus: Архитектура и быстрый старт

Курс закладывает фундамент понимания pull-модели мониторинга и структуры временных рядов. Вы освоите базовые компоненты системы и запустите работающий инстанс для сбора первых метрик.

1. Философия Pull-модели и архитектурные компоненты экосистемы Prometheus

Черная пятница. Трафик крупного интернет-магазина вырастает в десять раз. Система автомасштабирования Kubernetes реагирует на нагрузку и за пару минут поднимает 500 новых экземпляров сервиса оплаты. Спустя еще минуту центральный сервер мониторинга перестает отвечать, а дежурные инженеры слепнут в самый критический момент. Причина сбоя кроется не в баге или нехватке памяти, а в фундаментальной архитектуре старых систем мониторинга: 500 новых сервисов одновременно начали агрессивно отправлять свои метрики на центральный сервер, устроив ему непреднамеренную DDoS-атаку. Именно для решения подобных проблем в высокодинамичных средах инженеры SoundCloud создали Prometheus, полностью перевернув подход к сбору телеметрии.

Смена парадигмы: почему Push-модель ломается под нагрузкой

Исторически большинство систем мониторинга (например, StatsD, Graphite, Zabbix в активном режиме) строились на базе Push-модели. В этой парадигме каждый наблюдаемый узел или приложение содержит агента, который собирает локальные метрики и активно отправляет (пушит) их на центральный сервер.

На первый взгляд это звучит логично: приложение само знает, когда оно выполнило транзакцию, и сообщает об этом. Но в масштабах BigTech эта модель сталкивается с тремя критическими ограничениями:

  • Проблема перегрузки (Bottleneck). Сервер мониторинга становится узким местом. Он не контролирует входящий поток данных. Если в сети происходит сбой и 1000 агентов решают отправить накопленные метрики одновременно, сервер захлебывается в TCP-соединениях и падает.
  • Сложность конфигурации клиентов. Каждому микросервису необходимо передать конфигурацию: IP-адрес сервера мониторинга, порты, токены авторизации. При изменении адреса центрального сервера приходится обновлять настройки тысяч клиентов.
  • Слепота к падениям. Если от сервиса перестали поступать метрики, Push-модель не позволяет однозначно определить причину. Сервис завис? Упал процесс? Произошел разрыв сети? Или сервис просто простаивает без пользовательского трафика и ему нечего отправлять?
  • !Архитектура Push и Pull моделей

    Pull-модель: сервер диктует правила

    Prometheus использует диаметрально противоположный подход — Pull-модель. Приложения вообще ничего не знают о существовании центрального сервера мониторинга. Их единственная задача — выставить HTTP-эндпоинт (обычно /metrics), при обращении к которому приложение отдает свое текущее состояние в виде простого текста.

    Prometheus работает как веб-скрапер. Он содержит внутренний планировщик (Scrape Manager), который по расписанию (например, каждые секунд) обходит известные ему адреса, скачивает текст с метриками и сохраняет их в базу данных.

    Этот архитектурный сдвиг решает проблемы Push-модели на фундаментальном уровне:

    Во-первых, Prometheus сам контролирует нагрузку. Если сервер мониторинга начинает не справляться, он просто увеличивает интервал опроса или собирает данные медленнее. Приложения при этом не тратят ресурсы на попытки достучаться до упавшего сервера — они просто продолжают обновлять данные в локальной памяти, ожидая, когда за ними придут.

    Во-вторых, появляется бесплатный мониторинг доступности. Когда Prometheus пытается опросить таргет (цель) и получает ошибку соединения (Connection Refused) или таймаут, он автоматически генерирует синтетическую метрику up. Если сбор прошел успешно, метрика равна , если таргет недоступен — . Инженеру не нужно настраивать отдельные health-чеки (проверки жизнеспособности), сам факт успешного или неуспешного скрейпинга уже является надежным индикатором состояния сервиса.

    В-третьих, клиентские библиотеки становятся предельно легковесными. Им не нужно управлять очередями отправки, повторными попытками (retries) или сетевыми таймаутами. Вся логика клиента сводится к инкременту счетчиков в оперативной памяти и отдаче их при HTTP-запросе.

    Граничный случай: когда Pull не работает

    Pull-модель идеальна для долгоживущих процессов (веб-серверов, баз данных). Но как быть с cron-задачами или скриптами резервного копирования, которые запускаются, работают 3 секунды и завершаются? Prometheus физически не успеет их опросить, если его интервал скрейпинга составляет секунд.

    Для таких исключений в экосистеме существует Pushgateway. Это промежуточный кэширующий сервис. Короткоживущий скрипт перед завершением «пушит» свои финальные результаты в Pushgateway. Сам Pushgateway работает постоянно и предоставляет классический /metrics эндпоинт, с которого Prometheus забирает данные в штатном Pull-режиме. Таким образом, архитектурная чистота не нарушается.

    Service Discovery: мозг Pull-модели в динамике

    Главный вопрос, который возникает при знакомстве с Pull-моделью: откуда Prometheus знает, по каким IP-адресам ему нужно ходить? В статической инфраструктуре можно прописать адреса серверов в конфигурационном YAML-файле. Но в Kubernetes поды создаются и уничтожаются каждую минуту, их IP-адреса непредсказуемы.

    Здесь вступает в игру механизм Service Discovery (SD) — обнаружение сервисов. Prometheus не пытается угадать адреса, он делегирует эту задачу инфраструктуре.

    Prometheus умеет нативно интегрироваться с API Kubernetes, Consul, AWS EC2, Google Compute Engine и десятками других провайдеров. Процесс выглядит так:

  • Prometheus подключается к API Kubernetes и подписывается на события изменения подов.
  • Когда запускается новый микросервис, Kubernetes API сообщает Prometheus его новый внутренний IP-адрес и набор метаданных (лейблы, неймспейс).
  • Prometheus автоматически добавляет этот IP в свой внутренний пул таргетов и при следующем цикле начинает собирать с него метрики.
  • Инженеру достаточно один раз настроить правила Service Discovery, после чего мониторинг становится полностью автономным. Разработчики могут деплоить тысячи новых контейнеров, и они будут автоматически подхватываться системой мониторинга в ту же секунду, без единого изменения в конфигурации Prometheus.

    Анатомия экосистемы Prometheus

    Сам по себе бинарный файл Prometheus — это лишь ядро. В реальных продакшн-средах мониторинг строится из нескольких независимых компонентов, каждый из которых решает строго одну задачу, следуя философии Unix.

    !Экосистема Prometheus

    1. Prometheus Server (Ядро)

    Центральный узел, который выполняет три основные функции:
  • Retrieval (Сборщик): Модуль, реализующий логику Service Discovery и HTTP-скрейпинга. Он отвечает за то, чтобы вовремя постучаться в таргеты и забрать данные.
  • TSDB (Time Series Database): Встроенная база данных временных рядов. Метрики — это не реляционные данные, это непрерывный поток пар «метка времени — числовое значение». Использование обычных баз данных (вроде PostgreSQL) для таких задач крайне неэффективно. Кастомная TSDB в Prometheus оптимизирована под сверхбыструю запись (append-only) и способна сжимать данные так, что миллионы точек данных занимают считанные мегабайты на диске.
  • HTTP Server: Предоставляет API для выполнения запросов к сохраненным данным с помощью языка PromQL.
  • 2. Экспортеры (Exporters)

    Если вы написали собственное приложение на Go или Python, вы можете встроить в него библиотеку Prometheus, и оно будет само отдавать метрики. Но как мониторить ядро Linux, базу данных MySQL или аппаратный маршрутизатор Cisco, код которых вы не можете изменить?

    Для этого используются экспортеры — небольшие программы-переводчики. Они устанавливаются рядом с целевым сервисом, извлекают его специфичные метрики (например, читают системные файлы /proc и /sys в Linux) и конвертируют их в понятный для Prometheus текстовый формат, выставляя наружу HTTP-порт. Самый популярный пример — Node Exporter, который превращает любой Linux-сервер в таргет для Prometheus, отдавая метрики CPU, памяти, дисков и сети.

    3. Alertmanager

    Prometheus умеет вычислять сложные математические условия (например, «свободное место на диске уменьшается со скоростью и закончится через 4 часа»). Но сам Prometheus не отправляет письма и не звонит дежурным.

    Если условие срабатывает, Prometheus отправляет короткий сигнал в отдельный компонент — Alertmanager. Именно Alertmanager занимается дедупликацией (чтобы не отправить 100 писем об одной ошибке), группировкой алертов и их маршрутизацией в Slack, Telegram, PagerDuty или на электронную почту. Вынесение этой логики в отдельный бинарный файл позволяет масштабировать мониторинг и оповещения независимо друг от друга.

    4. Инструменты визуализации (Grafana)

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

    Де-факто стандартом визуализации в экосистеме является Grafana. Она подключается к Prometheus по API, отправляет ему PromQL-запросы, получает массивы чисел и отрисовывает их в виде графиков, спидометров и тепловых карт, которые можно вывести на большие экраны в офисе или использовать для ежедневного анализа производительности.

    Переход от активных агентов к централизованному сбору данных через HTTP-запросы в связке с динамическим обнаружением сервисов сделал Prometheus стандартом для cloud-native инфраструктуры. Эта архитектура гарантирует, что система мониторинга останется стабильной и предсказуемой даже в моменты жесточайших инфраструктурных штормов, предоставляя инженерам достоверные данные для принятия решений.

    2. Структура данных Time Series и четыре базовых типа метрик

    Строка http_requests_total{method="GET", status="200"} 1053 1699876543000 выглядит как техническая бессмыслица, но именно в таком текстовом формате приложения отдают свои метрики. В этой единственной строке заложен весь фундамент того, как Prometheus понимает состояние вашей инфраструктуры. Сервер мониторинга забирает миллионы таких строк каждую секунду, парсит их и укладывает в базу данных.

    Чтобы строить надежные системы алертинга и не обрушить сервер мониторинга в первый же день запуска в production, необходимо понимать анатомию этих текстовых строк и правила, по которым они группируются.

    Анатомия Time Series и метки (Labels)

    Prometheus хранит данные в виде временных рядов (Time Series). Временной ряд — это непрерывная последовательность значений, привязанных к меткам времени.

    Каждая строка, которую отдает приложение, состоит из четырех элементов:

  • Имя метрики (http_requests_total) — описывает измеряемую сущность.
  • Набор меток или лейблов ({method="GET", status="200"}) — пары ключ-значение, детализирующие метрику.
  • Значение (1053) — всегда число с плавающей точкой (float64).
  • Timestamp (1699876543000) — временная метка в миллисекундах (часто опускается, тогда Prometheus подставит время скрейпа).
  • Ключевая концепция, которую нужно усвоить: имя метрики плюс уникальный набор меток образуют один уникальный временной ряд.

    Если у вас есть метрика http_requests_total{method="GET", status="200"} и http_requests_total{method="POST", status="200"} — для базы данных Prometheus это два совершенно разных, независимых потока данных, которые пишутся на диск параллельно.

    !Структура временного ряда и кардинальность

    Ловушка кардинальности (Cardinality)

    Метки дают невероятную гибкость при фильтрации данных, но таят в себе главную опасность для производительности — взрыв кардинальности. Кардинальность — это общее количество уникальных временных рядов в вашей базе.

    Количество рядов для одной метрики вычисляется перемножением возможных значений всех её меток:

    Разберем классическую ошибку начинающих инженеров. Приложение обрабатывает запросы пользователей, и разработчик решает добавить ID пользователя в метки, чтобы знать, кто делает больше всего запросов: http_requests_total{method="GET", status="200", user_id="84756"}

    Если у приложения 3 HTTP-метода, 5 возможных статус-кодов и 100 000 активных пользователей, сервер мониторинга попытается создать уникальных временных рядов только для одной метрики. Это приведет к исчерпанию оперативной памяти (OOM) на сервере Prometheus и его падению.

    Метки должны содержать только ограниченный набор значений (перечисления). HTTP-методы, коды ответов, имена дата-центров, версии релизов — отличные кандидаты для меток. ID пользователей, email-адреса, полные URL с параметрами запроса — категорически запрещены.

    Четыре базовых типа метрик

    На уровне хранения в TSDB Prometheus не делает различий между типами метрик. Для базы данных всё это — просто числа float64, меняющиеся во времени. Типы метрик — это абстракция клиентских библиотек (клиентов, встроенных в код вашего приложения) и языка запросов. Они диктуют, как именно приложение должно обновлять значение и как инженер должен его запрашивать.

    1. Counter (Счетчик)

    Counter — это метрика, значение которой может только увеличиваться или сбрасываться в ноль при перезапуске приложения. Она никогда не уменьшается в процессе нормальной работы.

    Типичные примеры использования:

  • Общее количество обработанных HTTP-запросов.
  • Количество отправленных байт по сети.
  • Число возникших ошибок в коде.
  • Само по себе текущее значение счетчика (например, 45 392 запроса) абсолютно бесполезно. Никто не знает, накопилось это число за год работы сервера или за последние пять секунд. Ценность Counter заключается в возможности вычислить скорость изменения (rate) этого значения за единицу времени.

    Если приложение падает и перезапускается, счетчик обнуляется. Клиентская библиотека начинает считать с нуля. Математические функции Prometheus спроектированы так, чтобы распознавать такие сбросы (когда новое значение меньше предыдущего) и корректно рассчитывать итоговую скорость без провалов в графиках.

    2. Gauge (Датчик / Указатель)

    Gauge представляет собой числовое значение, которое может произвольно увеличиваться и уменьшаться во времени. Это снимок текущего состояния системы в конкретную миллисекунду.

    Типичные примеры использования:

  • Использование оперативной памяти (RAM).
  • Количество активных соединений с базой данных.
  • Текущая температура процессора.
  • Размер очереди сообщений (RabbitMQ, Kafka).
  • !Поведение Counter и Gauge во времени

    В отличие от счетчика, применять функции вычисления скорости (rate) к Gauge нельзя — это даст математическую бессмыслицу. Если размер очереди сообщений скачет от 10 до 100 и обратно, нас интересует само абсолютное значение, его среднее или пиковое состояние, но не скорость его бесконечного роста (которой нет).

    3. Histogram (Гистограмма)

    Когда SRE-инженеру нужно измерить время ответа базы данных или задержку HTTP-запросов (latency), использование Gauge для вычисления среднего значения (Average) — грубая ошибка. Среднее арифметическое скрывает выбросы. Если 99 пользователей получили ответ за 10 мс, а один ждал 10 секунд (10 000 мс), среднее время составит около 110 мс. График покажет норму, хотя один клиент получил катастрофический опыт. Нам нужны перцентили (например, 99-й перцентиль покажет, что 99% запросов уложились в X миллисекунд).

    Histogram решает эту задачу, распределяя наблюдаемые значения по заранее заданным корзинам (бакетам).

    Клиентская библиотека, настроенная на сбор гистограммы (например, http_request_duration_seconds), генерирует сразу несколько временных рядов:

  • _count — общее количество наблюдений (работает как Counter).
  • _sum — общая сумма всех наблюдаемых значений.
  • Набор рядов с суффиксом _bucket и специальной меткой le (less or equal — меньше или равно).
  • !Распределение запросов по бакетам гистограммы

    Бакеты в Prometheus всегда кумулятивные. Допустим, заданы бакеты: le="0.1", le="0.5", le="1.0" и le="+Inf" (бесконечность). Если приходит запрос, выполненный за 0.3 секунды, клиентская библиотека:

  • Проверит бакет 0.1. Значение 0.3 не меньше 0.1, бакет не трогаем.
  • Проверит бакет 0.5. Значение 0.3 меньше 0.5. Увеличиваем счетчик этого бакета на +1.
  • Проверит бакет 1.0. Значение 0.3 меньше 1.0. Увеличиваем счетчик этого бакета на +1.
  • Увеличит бакет +Inf на +1.
  • Кумулятивность означает, что бакет le="1.0" всегда включает в себя все значения из бакета le="0.5". Это позволяет серверу Prometheus позже, на этапе выполнения запроса, математически аппроксимировать любой перцентиль (90-й, 95-й, 99-й) на основе того, как быстро наполняются разные бакеты.

    4. Summary (Сводка)

    Summary исторически появилась как альтернатива гистограммам для расчета перцентилей. Как и Histogram, она создает ряды _count и _sum. Но вместо бакетов Summary вычисляет точные квантили (перцентили) прямо на стороне клиента, в памяти самого приложения, и отдает готовые ряды, например: http_request_duration_seconds{quantile="0.99"}.

    На первый взгляд это кажется удобным: серверу не нужно делать сложную математику, приложение отдает готовый 99-й перцентиль. Однако в распределенных системах BigTech этот тип метрики практически не используется из-за одного фатального математического ограничения.

    Перцентили нельзя агрегировать. Если у вас работает 10 экземпляров (подов) микросервиса, каждый из них отдаст свой собственный 99-й перцентиль времени ответа. Вы не можете сложить эти 10 значений и разделить на 10, чтобы получить 99-й перцентиль всего кластера. Среднее от перцентилей — это математический нонсенс, который приведет к ложным срабатываниям алертов.

    Histogram решает эту проблему элегантно: поскольку она отдает сырые счетчики бакетов, Prometheus может сложить значения одинаковых бакетов со всех 10 серверов (счетчики складывать можно!), и только потом, из этой агрегированной суммы, вычислить истинный 99-й перцентиль для всего кластера. Summary так не умеет, поэтому ее применение ограничено одиночными, не масштабируемыми сервисами.

    Текстовый формат, в котором метрики передаются по сети, является мощным контрактом между приложением и системой мониторинга. Грамотный выбор типа метрики на этапе написания кода определяет, сможете ли вы в будущем построить точный график и настроить надежный алерт, или ваши данные окажутся математически непригодными для анализа.

    3. Конфигурация статического таргета и развертывание первого инстанса Prometheus

    Многие enterprise-системы мониторинга требуют для старта развертывания тяжелой реляционной базы данных, брокера сообщений и установки агентов с root-правами на каждый сервер. Prometheus ломает этот паттерн. Вся система — это один статически скомпилированный бинарный файл, который не имеет внешних зависимостей. Для его запуска нужен только один текстовый файл конфигурации. Эта архитектурная простота позволяет развернуть полноценный сервер мониторинга за пару минут, а при сбое — перенести его на другой узел простым копированием конфигурации и директории с данными.

    Анатомия конфигурационного файла prometheus.yml

    Поведение Prometheus полностью определяется декларативным YAML-файлом. В production-средах этот файл никогда не правится руками на сервере — он генерируется через системы управления конфигурациями (Ansible, Chef) или доставляется через ConfigMap в Kubernetes.

    Файл имеет строгую иерархию и логически разделен на несколько блоков. Главные из них для базового старта — global и scrape_configs.

    Блок global задает параметры по умолчанию для всего сервера.

    Параметр scrape_interval определяет базовый пульс системы — как часто Prometheus будет опрашивать свои таргеты. В BigTech стандартом де-факто считается интервал в 10 или 15 секунд. Меньшие значения (например, 1 секунда) создают избыточную нагрузку на сеть и экспортеры, а также приводят к экспоненциальному росту базы данных. Большие значения (1 минута и более) делают мониторинг слепым к микро-сбоям: если сервис упал и поднялся за 30 секунд, минутный интервал может этого не заметить.

    Параметр scrape_timeout — это жесткий лимит времени на ожидание ответа от таргета. Если приложение задумалось и собирает свои метрики дольше 10 секунд, Prometheus принудительно разорвет HTTP-соединение и пометит сбор как неудачный.

    > Важное правило конфигурации: scrape_timeout всегда должен быть строго меньше, чем scrape_interval. Иначе наслаивающиеся друг на друга зависшие запросы быстро исчерпают пул соединений сервера.

    Блок scrape_configs — это сердце pull-модели. Здесь описывается, куда именно Prometheus должен ходить за данными. Каждая логическая группа таргетов описывается как отдельный job.

    При использовании static_configs мы жестко прописываем IP-адреса и порты. В отличие от Service Discovery, где список формируется динамически, статический конфиг требует ручного обновления при добавлении новых серверов.

    Обратите внимание на концепцию job (задача) и instance (экземпляр). В примере выше payment_backend — это job, описывающий сервис целиком. А 10.0.1.15:8080 и 10.0.1.16:8080 — это конкретные инстансы этого сервиса. На этапе сбора метрик Prometheus автоматически прикрепит к каждому временному ряду лейблы job="payment_backend" и instance="10.0.1.15:8080". Это позволяет в дальнейшем легко агрегировать потребление памяти как по конкретному серверу, так и по всему кластеру платежного бэкенда разом.

    !Структура конфигурации Prometheus

    Подготовка инфраструктуры и Docker Compose

    В современной инженерии локальные бинарные файлы запускаются редко. Стандартом для предсказуемого развертывания является Docker. Это гарантирует, что среда изолирована, а версия Prometheus строго зафиксирована.

    Для запуска потребуется создать директорию проекта и два файла: prometheus.yml (конфигурация) и docker-compose.yml (инфраструктура).

    Создадим конфигурацию, которая решает две образовательные задачи. Во-первых, Prometheus будет мониторить сам себя (dogfooding) — он отдает отличные метрики о своем внутреннем состоянии по адресу localhost:9090/metrics. Во-вторых, добавим заведомо недоступный таргет, чтобы увидеть, как система обрабатывает сетевые ошибки.

    Содержимое prometheus.yml:

    Теперь опишем инфраструктуру в docker-compose.yml:

    В этом манифесте скрыто несколько критически важных SRE-практик. Первая — явное указание версии образа (v2.45.0), а не тега latest. Использование latest в production недопустимо, так как неконтролируемое обновление мажорной версии при перезапуске контейнера может сломать совместимость формата базы данных.

    Вторая практика — разделение состояния. Конфигурационный файл монтируется в режиме read-only (:ro), защищая его от случайной перезаписи процессом внутри контейнера. При этом база данных вынесена в именованный Docker-volume prometheus_data. Если удалить контейнер и создать его заново, исторические метрики не потеряются.

    Третья деталь — переопределение директивы command. По умолчанию образ Prometheus запускается с базовыми флагами. Явно прописывая пути к конфигурации (--config.file) и директории данных (--storage.tsdb.path), мы берем полный контроль над процессом.

    Запуск и анализ внутреннего состояния

    Запуск инфраструктуры выполняется одной командой в директории с файлами:

    Флаг -d (detach) отправляет процесс в фон. Чтобы убедиться, что сервер стартовал без фатальных ошибок парсинга YAML, необходимо проверить логи:

    Успешный старт сопровождается строками Server is ready to receive web requests и TSDB started. Если в prometheus.yml допущена ошибка (например, неверный отступ), процесс упадет немедленно, и лог укажет точную строку с синтаксической ошибкой.

    После успешного старта веб-интерфейс доступен по адресу http://localhost:9090. Это не инструмент для построения красивых дашбордов (для этого используется Grafana), а мощная консоль администратора и среда отладки.

    Первое место, куда смотрит инженер после деплоя конфигурации — это страница http://localhost:9090/targets. Здесь отображается статус всех эндпоинтов, описанных в scrape_configs.

    !Интерфейс страницы Targets

    На этой странице таргет localhost:9090 (сам Prometheus) будет иметь статус UP, подсвеченный зеленым цветом. Рядом отображается время последнего успешного скрейпа (Last Scrape) и длительность самого HTTP-запроса (Scrape Duration).

    Таргет 192.0.2.200:80 перейдет в статус DOWN, подсвеченный красным. В колонке Error появится системная причина сбоя, например context deadline exceeded (сработал scrape_timeout) или connection refused.

    Именно здесь материализуется концепция синтетической метрики up. Prometheus не просто пишет логи об ошибках сети, он конвертирует статус HTTP-запроса во временной ряд. Если перейти во вкладку Graph (главная страница интерфейса) и ввести запрос up, система вернет таблицу: up{job="prometheus", instance="localhost:9090"} = 1 up{job="broken_service", instance="192.0.2.200:80"} = 0

    Значение 1 означает успешный сбор метрик, 0 — провал. На базе этой фундаментальной метрики в дальнейшем строятся базовые алерты доступности инфраструктуры.

    Физическая структура хранения на диске

    Чтобы уверенно эксплуатировать Prometheus, необходимо понимать, что происходит внутри примонтированного тома prometheus_data. Если зайти внутрь контейнера и посмотреть содержимое директории /prometheus, мы увидим следующую структуру:

    Prometheus TSDB оптимизирована для записи миллионов точек в секунду. Чтобы достичь такой скорости, данные не пишутся сразу в тяжелые файлы на диске. Они накапливаются в оперативной памяти (в структуре Head block).

    Однако хранение только в RAM несет риск потери данных при внезапном отключении питания или падении процесса (OOM Kill). Для защиты от этого используется механизм WAL (Write-Ahead Log) — директория wal. Все входящие метрики сначала в виде сырого потока байт дописываются в конец файлов WAL (append-only операция, которая выполняется диском мгновенно), и только потом попадают в оперативную память.

    Если контейнер prometheus_core принудительно убить командой kill -9, при следующем старте сервер прочитает файлы из папки wal и полностью восстановит потерянные из оперативной памяти временные ряды.

    Каждые два часа данные из оперативной памяти сжимаются, индексируются и сбрасываются на диск в виде неизменяемых (immutable) блоков. Только после успешного создания такого блока старые файлы WAL удаляются. Эта архитектура делает Prometheus невероятно устойчивым к аварийным завершениям работы, что критично для систем мониторинга, которые должны оставаться живыми даже тогда, когда вся остальная инфраструктура рушится.

    Развернув базовый инстанс и разобравшись с конфигурацией статических таргетов, мы получили фундамент. Настроенный сервер уже непрерывно собирает метрики и пишет их в TSDB. Следующим шагом становится извлечение этих данных и превращение сырых чисел в осмысленную информацию о поведении системы с помощью языка запросов.