Урок по треку Data Engineering 6 мин

Батч и стриминг: окна, время, watermark

Когда батч, когда стриминг, окна, event time и processing time, watermark, опоздавшие события, Lambda и Kappa.

Батч обрабатывает ограниченный набор данных целиком: «все заказы за вчера». Стриминг обрабатывает неограниченный поток по мере поступления: «каждое событие через секунды после того, как оно произошло». Выбор между ними это компромисс между свежестью, сложностью и стоимостью.

Когда что

Батч подходит, когда свежесть в часы или сутки устраивает: финансовая отчётность, ежедневные витрины, обучение моделей. Проще писать, тестировать, пересчитывать; дешевле.

Стриминг нужен, когда ценность данных быстро падает: антифрод, мониторинг, персонализация в сессии, алерты, оперативные дашборды. Сложнее: состояние, порядок событий, опоздания, гарантии доставки, эксплуатация 24/7.

Частый компромисс: микробатчи каждые 1-15 минут (Spark Structured Streaming по умолчанию работает так) или частые батчи из оркестратора.

Инструменты: Kafka как транспорт и буфер, Apache Flink и Spark Structured Streaming для обработки, Kafka Streams как библиотека внутри сервиса, ClickHouse как приёмник с собственными движками для чтения из Kafka.

Время события и время обработки

  • Event time: когда событие произошло (время клика на телефоне).
  • Processing time: когда система его обработала.

Между ними бывает разрыв от миллисекунд до суток: телефон был без сети, продюсер ретраил, консьюмер лежал. Если считать «клики за минуту» по processing time, сбой консьюмера на 10 минут нарисует провал и затем пик, которых в реальности не было. Для корректной аналитики окна строят по event time.

Окна

  • Tumbling (фиксированные): непересекающиеся окна одного размера: каждая минута, каждый час.
  • Sliding/hopping (скользящие): окна размера W со сдвигом S < W: «за последние 10 минут, обновляется каждую минуту». Событие попадает в несколько окон.
  • Session: окно на пользователя закрывается после паузы без событий.

Watermark и опоздавшие события

Если события приходят не по порядку, когда можно закрыть окно 10:00-10:01 и выдать результат? Watermark это оценка «события с временем меньше T больше не придут». Часто его считают как максимальное увиденное event time минус допустимую задержку:

watermark = max(event_time) - allowed_lateness

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

Компромисс: большая задержка watermark даёт полноту, но результат выходит позже и больше состояния в памяти; маленькая даёт быстрые, но неполные результаты.

Состояние

Агрегации, джойны потоков, дедупликация требуют состояния: что уже видели, какие окна открыты. Состояние хранится локально (у Flink в RocksDB) и периодически сохраняется в чекпоинт, чтобы после падения продолжить с того же места. Важно ограничивать состояние по времени (TTL), иначе дедупликация «по всем event_id за всё время» съест всю память.

Гарантии обработки

  • At-most-once: событие обработается не больше одного раза, может потеряться.
  • At-least-once: не потеряется, но может обработаться повторно. Самый частый режим.
  • Exactly-once: эффект как от ровно одной обработки. На практике достигается либо транзакционной связкой источник-обработка-приёмник (чекпоинты Flink и транзакции Kafka), либо at-least-once плюс идемпотентный приёмник (upsert по ключу, дедупликация по id события).

Lambda и Kappa

  • Lambda: два контура: батч считает точно, стриминг быстро и приблизительно, результаты объединяются. Минус: две реализации одной логики, которые расходятся.
  • Kappa: только стриминг; пересчёт истории делается повторным прочтением лога (Kafka с долгим хранением) тем же кодом.

Сейчас часто встречается упрощённый вариант: стриминг в lakehouse или ClickHouse плюс периодический батч-пересчёт последних дней для исправления опозданий.

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

  • Окна по времени обработки, когда нужен бизнес-смысл по времени события.
  • Нет политики для опоздавших событий: они молча теряются.
  • Состояние без TTL растёт до падения.
  • Exactly-once «из коробки» в рекламных слайдах вместо идемпотентного приёмника.
  • Стриминг там, где хватило бы батча раз в час.

Что спросят на собесе

  • Когда нужен стриминг, а когда батч или микробатч.
  • Event time против processing time.
  • Типы окон, watermark и опоздавшие события.
  • At-least-once, at-most-once, exactly-once и как добиться последнего.
  • Lambda против Kappa.

Закрепите за 5 минут

После урока в тренажёре 3-5 проверочных вопросов, дальше модуль уходит в повторения.