Интеграции: Kafka и S3

ClickHouse умеет сам забирать данные из Kafka и читать/писать файлы в S3.

Интеграционный движок — таблица, за которой стоит не локальное хранилище, а внешний источник (Kafka, S3, базы данных), с которым ClickHouse общается напрямую.

Проблема потоковой загрузки

Мы знаем: вставлять по событию нельзя (too many parts), нужно батчить. Но события часто идут потоком через Kafka — распределённую очередь сообщений. ClickHouse решает это встроенным движком Kafka, который сам читает сообщения и собирает их в батчи.

Связка Kafka → ClickHouse

Классическая схема из трёх частей: таблица-движок Kafka (читает поток), таблица MergeTree (хранит данные) и материализованное представление-«мост» между ними:

-- 1) Источник: читает сообщения из топика Kafka
CREATE TABLE events_queue
(
    user_id UInt32,
    event   String,
    ts      DateTime
)
ENGINE = Kafka
SETTINGS kafka_broker_list = 'kafka:9092',
         kafka_topic_list  = 'events',
         kafka_format      = 'JSONEachRow';

-- 2) Хранилище
CREATE TABLE events
(
    user_id UInt32,
    event   String,
    ts      DateTime
)
ENGINE = MergeTree
ORDER BY (ts, user_id);

-- 3) Мост: переливает данные из очереди в хранилище батчами
CREATE MATERIALIZED VIEW events_mv TO events AS
SELECT user_id, event, ts FROM events_queue;

ClickHouse сам вычитывает Kafka пачками и через MV пишет в MergeTree аккуратными батчами — проблема мелких вставок решена.

Работа с S3

S3 (и совместимые объектные хранилища) — дешёвое место для огромных архивов. ClickHouse умеет читать и писать файлы прямо там через функцию/движок s3. Это удобно для разовой загрузки дампов или выгрузки данных:

-- Прочитать CSV-файлы прямо из S3 и вставить в таблицу
INSERT INTO events
SELECT *
FROM s3('https://bucket.s3.amazonaws.com/data/*.csv',
        'CSV',
        'user_id UInt32, event String, ts DateTime');

Поддерживается маска *.csv — можно залить сразу множество файлов. Так же легко выгрузить результат запроса в S3.

Сводка интеграций

ИсточникДвижок/функцияПрименение
KafkaKafkaпотоковая загрузка событий
S3s3архивы, дампы, обмен файлами
СУБДMySQL, PostgreSQLчтение внешних таблиц

Как работает под капотом

Движок Kafka ведёт себя как consumer: вычитывает сообщения, отдаёт их связанному MV, и тот пишет в MergeTree. Прочитанное из Kafka-таблицы «исчезает» (сообщение считается потреблённым) — поэтому читать из неё напрямую нельзя, только через MV-мост. Движок s3 обращается к объектному хранилищу по HTTP при каждом запросе.

Частые ошибки

  • Читать из Kafka-таблицы напрямую SELECT-ом. Это «съест» сообщения; данные потребляет только MV-мост.
  • Забыть про формат. Нужно указать kafka_format / формат в s3(...), соответствующий данным (JSONEachRow, CSV…).
  • Ждать транзакционных гарантий Kafka «из коробки». Возможны дубликаты; учитывайте это (например, ReplacingMergeTree).

Итоги

  • Движок Kafka сам читает поток и через MV пишет батчами в MergeTree.
  • Функция/движок s3 читает и пишет файлы в объектном хранилище, поддерживает маски.
  • Есть интеграции и с внешними СУБД (MySQL, PostgreSQL).
  • Из Kafka-таблицы читают только через MV-мост, не напрямую.
Проверьте себя
1. Как обычно строят потоковую загрузку из Kafka в ClickHouse?
AINSERT по одному сообщению вручную
BТаблица-движок Kafka + MergeTree + материализованное представление-мост между ними
CТолько через S3
DНикак, ClickHouse не дружит с Kafka
2. Почему нельзя читать из Kafka-таблицы обычным SELECT?
ASELECT там запрещён синтаксисом
BЧтение потребляет сообщения, и они исчезнут для MV-моста; читать нужно через MV
CKafka-таблица всегда пуста
DЭто замедляет S3