Кейс: аналитика событий (Kafka + ClickHouse)
↑ 8.4 Backend System Design · ← Предыдущая · → Следующая
Зачем это на собесе
Пример потоковой аналитики: сбор миллионов событий и быстрые агрегаты.
Объяснение
Требования: принимать события (клики, действия, метрики) с высокой скоростью (сотни тысяч/с), хранить месяцы и годы, отвечать на агрегатные запросы за секунды, дашборды, допускается небольшая задержка (секунды).
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).
- Ключ сортировки определяет производительность запросов — проектируйте под них.
Практика
- Настройте поток Kafka → ClickHouse и измерьте пропускную способность.
- Создайте materialized view почасовых агрегатов.
- Добавьте TTL и сравните размер до и после сжатия.
Вопросы с ответами
Почему Kafka перед ClickHouse?
Буфер для пиков и сбоев, возможность replay и независимые потребители.
Почему ClickHouse не любит построчные вставки?
Каждая вставка создаёт часть данных; мелкие вставки перегружают фоновые слияния.