Временные ряды: TimescaleDB, InfluxDB, VictoriaMetrics

↑ 4.3 Поиск и специализированные БД · ← Предыдущая · → Следующая

Желательно~6 мин чтенияУровень: middle

Зачем это на собесе

Метрики, датчики, события и финансовые котировки — данные, где запись идёт непрерывным потоком, а запросы почти всегда «за период с агрегацией». Вопрос «где хранить метрики или IoT-данные» проверяет знание специализированных движков и понимание кардинальности, retention и downsampling.

Подтемы

  • Особенности временных рядов
  • Кардинальность, retention, downsampling
  • TimescaleDB
  • InfluxDB и VictoriaMetrics
  • ClickHouse и партиции PostgreSQL как альтернативы

Объяснение

Что такое временной ряд

Последовательность значений с временной меткой: температура раз в секунду, загрузка процессора, цена акции. Характер нагрузки:

  • данные почти только добавляются и почти не меняются;
  • запросы берут диапазон по времени и агрегируют (среднее, максимум, квантили);
  • старые данные теряют ценность и подлежат сжатию или удалению.

Понятия

ПонятиеСмысл
Метрика и теги (labels)имя измерения и набор меток (host, region, service)
Кардинальностьчисло уникальных комбинаций меток; её рост главная причина проблем
Retentionсрок хранения данных
Downsamplingхранение старых данных с меньшей детализацией (минутные вместо секундных)
Continuous aggregateзаранее посчитанная агрегация, которая обновляется автоматически

Высокая кардинальность (например, метка user_id или request_id) создаёт миллионы рядов и убивает производительность большинства TSDB. В метки кладут ограниченные значения, а уникальные идентификаторы держат в логах или трассах.

TimescaleDB

Расширение PostgreSQL. Обычная таблица превращается в hypertable, которая автоматически делится на «чанки» по времени. Остаётся SQL, транзакции и все инструменты PostgreSQL.

CREATE TABLE metrics (
  time   timestamptz NOT NULL,
  device text        NOT NULL,
  value  double precision
);
SELECT create_hypertable('metrics', 'time');
 
-- агрегация по 5-минутным окнам
SELECT time_bucket('5 minutes', time) AS bucket, device, avg(value)
FROM metrics
WHERE time > now() - interval '1 day'
GROUP BY bucket, device
ORDER BY bucket;

Поддерживает сжатие старых чанков, политики retention и continuous aggregates. Подходит, когда нужны SQL и связь с обычными таблицами.

InfluxDB и VictoriaMetrics

СистемаОсобенности
InfluxDBспециализированная TSDB, язык Flux и SQL-подобный InfluxQL (в новых версиях добавлен SQL), отдельная экосистема сбора данных
VictoriaMetricsхранилище совместимо с Prometheus (PromQL), хорошо сжимает, экономно по памяти, просто масштабируется
Prometheus TSDBлокальное хранилище Prometheus, хорошее для одного узла и короткого срока

Для инфраструктурных метрик обычно связка Prometheus (сбор) и VictoriaMetrics (долгое хранение) или Thanos и Mimir (долгое хранение метрик).

Альтернативы без специализированной TSDB

  • PostgreSQL с партиционированием по времени (партиционирование) подходит для умеренных объёмов.
  • ClickHouse (ClickHouse) справляется с миллиардами строк и аналитикой, часто выбирают для событий и логов.
flowchart TD
    A["Данные с временной меткой"] --> B{"Что за данные?"}
    B -- "метрики инфраструктуры" --> C["Prometheus + VictoriaMetrics / Mimir"]
    B -- "IoT, нужен SQL и связи" --> D["TimescaleDB"]
    B -- "события и логи,<br/>тяжёлая аналитика" --> E["ClickHouse"]
    B -- "немного, умеренный поток" --> F["PostgreSQL + партиции"]

Нюансы и подводные камни

  • Кардинальность. Не используйте в метках user_id, url, идентификаторы запросов.
  • Retention и downsampling планируйте сразу. Хранить секундные данные годами дорого и не нужно.
  • Время. Храните в UTC, следите за часами источников и задержкой доставки (запаздывающие данные).
  • Пакетная вставка. Пишите пачками, а не по одной строке.
  • Запросы по диапазону времени. Всегда ограничивайте период, иначе читается весь ряд.
  • Подсчёт квантилей (p95, p99) по агрегированным данным неточен: храните гистограммы, если нужны точные перцентили.

Вопросы с ответами

Связанные темы