ksqlDB: SQL над потоками

Урок-обзор: как делать ту же потоковую обработку, что и в Streams, но декларативным SQL — без кода на Java.

ksqlDB — движок, позволяющий описывать обработку потоков Kafka на SQL: вы объявляете STREAM и TABLE над топиками и пишете непрерывные запросы, которые работают вечно, обновляясь на каждом событии.

Зачем это нужно

Kafka Streams мощна, но требует писать и деплоить Java/Scala-приложение. Часто задача проще: «отфильтруй события дороже 1000» или «считай заказы по городам в окне». Для таких вещей ksqlDB даёт знакомый SQL: аналитик или инженер описывает преобразование запросом, и оно начинает выполняться над потоком в реальном времени.

STREAM и TABLE

Те же два понятия, что KStream/KTable, но в SQL-обёртке. STREAM — поток событий поверх топика; TABLE — изменяемое состояние по ключу.

-- объявляем поток над топиком orders
CREATE STREAM orders (
  order_id VARCHAR,
  city     VARCHAR,
  amount   DOUBLE
) WITH (KAFKA_TOPIC='orders', VALUE_FORMAT='JSON');

-- непрерывный запрос: только крупные заказы -> новый топик
CREATE STREAM big_orders AS
  SELECT * FROM orders WHERE amount > 1000;

Запрос CREATE STREAM ... AS SELECT создаёт постоянный поток: он живёт, читая orders и дописывая подходящие события в новый топик. Это не разовый SELECT, а вечно работающее преобразование.

Агрегация в окне

CREATE TABLE orders_per_city AS
  SELECT city, COUNT(*) AS cnt
  FROM orders
  WINDOW TUMBLING (SIZE 5 MINUTES)
  GROUP BY city;

Результат — TABLE, которая поддерживает счётчик заказов по городам за 5-минутные окна, обновляясь на каждом новом заказе.

Push против pull

Тип запросаПоведение
push (EMIT CHANGES)подписка: отдаёт новые результаты по мере событий, не завершается
pullразовая выборка текущего значения из материализованной таблицы

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

ksqlDB — это, по сути, надстройка над Kafka Streams: ваш SQL транслируется в Streams-топологию, которая и выполняет работу. Поэтому всё, что верно для Streams (параллелизм по партициям, локальное состояние, changelog-топики, отказоустойчивость), верно и здесь — просто скрыто за SQL. Push-запрос EMIT CHANGES — это непрерывная подписка на изменения; pull-запрос обращается к материализованной таблице состояний как к обычной БД. ksqlDB не заменяет аналитическое хранилище: его сила — в потоковых преобразованиях на лету, а не в произвольной аналитике по всей истории.

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

  • Ждать от ksqlDB полноценной OLAP-БД. Это потоковый движок; тяжёлую аналитику по истории делайте в ClickHouse/хранилище.
  • Путать push и pull. Push-запрос не завершается (это подписка); pull — разовая выборка из таблицы.
  • Забыть VALUE_FORMAT / схему. Без описания формата ksqlDB не разберёт байты сообщения.

Итоги

  • ksqlDB описывает потоковую обработку декларативным SQL над STREAM и TABLE.
  • Непрерывные запросы (CREATE ... AS SELECT) работают вечно, обновляясь на каждом событии.
  • Под капотом это Kafka Streams; ksqlDB — про стриминг, а не про OLAP по всей истории.
Проверьте себя
1. Что делает CREATE STREAM big_orders AS SELECT ... WHERE amount > 1000?
AРазово выбирает строки
BСоздаёт вечно работающий поток, дописывающий подходящие события в новый топик
CУдаляет топик orders
DМеняет схему
2. Чем push-запрос (EMIT CHANGES) отличается от pull?
APush быстрее
BPush — подписка, отдающая новые результаты и не завершающаяся; pull — разовая выборка из таблицы
CPull работает только с файлами
DРазницы нет
3. Что лежит под ksqlDB?
AОтдельная СУБД
BKafka Streams: SQL транслируется в Streams-топологию
CZooKeeper
DПрямой доступ к диску брокера