Кейс: аналитика событий (Kafka + ClickHouse)

↑ 8.4 Backend System Design · ← Предыдущая · → Следующая

Обязательно~3 мин чтенияУровень: senior

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

Пример потоковой аналитики: сбор миллионов событий и быстрые агрегаты.

Объяснение

Требования: принимать события (клики, действия, метрики) с высокой скоростью (сотни тысяч/с), хранить месяцы и годы, отвечать на агрегатные запросы за секунды, дашборды, допускается небольшая задержка (секунды).

flowchart LR
  A[Клиенты и сервисы] -->|HTTP/SDK| G[Ingest API]
  G --> KKafka: events
  K --> C[Consumers / Kafka engine]
  C --> CH[(ClickHouse)]
  K --> S[Stream processing]
  CH --> BI[Grafana / BI / API]

Решения:

ВопросРешение
Приёмstateless ingest-API, валидация, батчирование, ответ 202
БуферKafka: переживает пики и сбои хранилища, replay
Загрузкапакетная вставка большими блоками (ClickHouse не любит построчные INSERT): Kafka engine + materialized view или консьюмер с батчами по 10–100 тыс.
Схемаширокая таблица событий: event_time, user_id, session_id, type, props (JSON); MergeTree, PARTITION BY toYYYYMM(event_time), ORDER BY (type, user_id, event_time)
ДедупликацияReplacingMergeTree или id события; идемпотентная вставка
Агрегатыmaterialized views/проекции для типовых запросов (по часам, дням)
ХранениеTTL, tiered storage (холодные данные на дешёвом диске), сжатие
КардинальностьLowCardinality(String), осторожно с props
Приватностьне хранить лишние персональные данные, псевдонимизация
Надёжностьрепликация (ReplicatedMergeTree), шарды по user_id
CREATE TABLE events (
  event_time DateTime, user_id UInt64, type LowCardinality(String), props String
) ENGINE = MergeTree PARTITION BY toYYYYMM(event_time) ORDER BY (type, user_id, event_time)
TTL event_time + INTERVAL 13 MONTH;
 
SELECT toStartOfHour(event_time) h, count() FROM events WHERE type = 'click' AND event_time > now() - INTERVAL 1 DAY GROUP BY h ORDER BY h;

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

  • Частые мелкие вставки создают много «частей» и перегружают слияния.
  • Точные UPDATE/DELETE в ClickHouse дороги: моделируйте append-only.
  • Поздние и дублирующиеся события: окна по времени события и дедупликация.
  • Схема событий версионируется (Schema Registry).
  • Ключ сортировки определяет производительность запросов — проектируйте под них.

Практика

  1. Настройте поток Kafka → ClickHouse и измерьте пропускную способность.
  2. Создайте materialized view почасовых агрегатов.
  3. Добавьте TTL и сравните размер до и после сжатия.

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

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