ClickHouse как Prometheus long-term storage
ClickHouse поддерживает два режима работы с Prometheus: нативный endpoint для мониторинга самого ClickHouse (expose_metrics, GA) и роль long-term storage для внешних Prometheus-метрик (remote_write/remote_read). Эти два режима независимы и настраиваются отдельно. Данный урок посвящён второму режиму — получению и хранению внешних Prometheus-метрик через remote_write.
Подробности о нативном Prometheus endpoint (expose_metrics) и нативном TimeSeries engine рассмотрены в Модуле 13 урок 07.
Архитектура: remote_write vs expose_metrics
Ключевое различие:
expose_metrics— ClickHouse как источник метрикremote_write/remote_read— ClickHouse как хранилище метрик
Шаг 1: Создать таблицу ENGINE = TimeSeries
remote_write handler ожидает существующую таблицу ENGINE = TimeSeries. Создайте таблицу ДО добавления remote_write секции в prometheus.xml. Если таблица не существует, ClickHouse отклонит все входящие remote_write запросы с ошибкой “table not found”.
-- Создать базу данных и таблицу для хранения Prometheus-метрик
CREATE DATABASE IF NOT EXISTS prometheus;
-- TimeSeries engine автоматически создаёт внутренние таблицы:
-- prometheus.metrics_data -- сами данные (timestamp, value)
-- prometheus.metrics_tags -- теги метрик (label_name, label_value)
-- prometheus.metrics_names -- имена метрик
CREATE TABLE prometheus.metrics ENGINE = TimeSeries;
-- Проверить, что внутренние таблицы созданы
SHOW TABLES FROM prometheus;
-- metrics
-- metrics_data
-- metrics_tags
-- metrics_metrics (имена метрик)
Шаг 2: Настроить handlers в prometheus.xml
<!-- /etc/clickhouse-server/config.d/prometheus.xml -->
<clickhouse>
<prometheus>
<port>9363</port>
<handlers>
<!-- Handler 1: expose_metrics (мониторинг самого ClickHouse) -->
<expose_metrics_handler>
<url>/metrics</url>
<handler>
<type>expose_metrics</type>
<metrics>true</metrics>
<asynchronous_metrics>true</asynchronous_metrics>
<events>true</events>
<errors>true</errors>
</handler>
</expose_metrics_handler>
<!-- Handler 2: remote_write (приём метрик от Prometheus) -->
<write_handler>
<url>/write</url>
<handler>
<type>remote_write</type>
<table>prometheus.metrics</table>
</handler>
</write_handler>
<!-- Handler 3: remote_read (отдача метрик Prometheus/Grafana) -->
<read_handler>
<url>/read</url>
<handler>
<type>remote_read</type>
<table>prometheus.metrics</table>
</handler>
</read_handler>
</handlers>
</prometheus>
</clickhouse>
Шаг 3: Настроить Prometheus для remote storage
# prometheus.yml -- remote storage конфигурация
# Prometheus будет писать ВСЕ собранные метрики в ClickHouse
remote_write:
- url: "http://clickhouse:9363/write"
# Опциональные настройки:
queue_config:
capacity: 10000
max_shards: 200
max_backoff: 100ms
remote_read:
- url: "http://clickhouse:9363/read"
read_recent: true # Читать свежие данные (не только из TSDB)
# Стандартная конфигурация scrape для мониторинга самого ClickHouse
scrape_configs:
- job_name: 'clickhouse'
static_configs:
- targets: ['clickhouse:9363'] # expose_metrics handler
Проверка работы remote_write
После применения конфигурации Prometheus начнёт передавать метрики в ClickHouse. Проверить:
-- Проверить, что данные поступают
SELECT count() FROM prometheus.metrics;
-- Если > 0 -- remote_write работает
-- Посмотреть первые записи
SELECT *
FROM prometheus.metrics
LIMIT 5
FORMAT Vertical;
-- Запрос метрик по имени (аналог PromQL metric{labels})
SELECT
metric_name,
toDateTime(timestamp) AS ts,
value
FROM prometheus.metrics
WHERE metric_name = 'up'
ORDER BY ts DESC
LIMIT 10;
SQL-запросы к Prometheus-метрикам в ClickHouse
Одно из преимуществ хранения метрик в ClickHouse — возможность использовать полный SQL для анализа:
-- Среднее значение метрики за последний час, по 5-минутным интервалам
SELECT
toStartOfFiveMinutes(toDateTime(timestamp)) AS interval,
avg(value) AS avg_value
FROM prometheus.metrics
WHERE metric_name = 'process_cpu_seconds_total'
AND timestamp >= toUnixTimestamp(now() - INTERVAL 1 HOUR)
GROUP BY interval
ORDER BY interval;
-- Топ-10 метрик по количеству записей
SELECT
metric_name,
count() AS sample_count,
min(toDateTime(timestamp)) AS first_seen,
max(toDateTime(timestamp)) AS last_seen
FROM prometheus.metrics
GROUP BY metric_name
ORDER BY sample_count DESC
LIMIT 10;
Рекомендации для production
Для высоконагруженного production long-term storage рассмотрите альтернативу TimeSeries engine — ручную MergeTree схему (подробнее в Модуле 13 урок 07):
-- Production-рекомендуемый подход: ручная MergeTree-схема (GA, полный контроль)
CREATE TABLE prometheus.metrics_manual (
metric_name LowCardinality(String),
labels Map(String, String),
timestamp DateTime64(3) CODEC(Delta, ZSTD(1)),
value Float64 CODEC(Gorilla, LZ4)
) ENGINE = MergeTree()
PARTITION BY toYYYYMM(timestamp)
ORDER BY (metric_name, labels, timestamp)
TTL timestamp + INTERVAL 90 DAY;
Ключевые выводы
remote_writehandler принимает Prometheus-метрики от внешних источников и записывает их в указаннуюENGINE = TimeSeriesтаблицу. Это отдельный handler отexpose_metrics.remote_readhandler отвечает Prometheus/Grafana на запросы исторических метрик из ClickHouse. Позволяет Grafana прозрачно читать данные из ClickHouse через стандартный Prometheus remote_read API.expose_metricsиremote_write/remote_read— независимые handlers на одном порту (9363). Можно использовать все три одновременно или только нужные.- Создайте таблицу
ENGINE = TimeSeriesдо настройкиremote_writehandler: ClickHouse отклоняет remote_write запросы, если таблица не существует. Порядок: CREATE TABLE -> обновить prometheus.xml -> перезагрузить конфигурацию. - SQL-аналитика Prometheus-метрик — ключевое преимущество ClickHouse как long-term storage: полный SQL (JOIN, GROUP BY, window functions) над накопленными метриками без PromQL ограничений.