Learning Platform
Глоссарий Troubleshooting
Урок 02.01 · 18 мин
Средний
Batch ProcessingStream ProcessingLambda ArchitectureKappa ArchitectureDAG

Batch vs streaming: фундаментальный сдвиг

Большинство дата-инженеров приходят в streaming с опытом batch — Spark, Airflow, dbt, Hive. Технически batch и streaming могут решать одни и те же задачи. Но ментальный сдвиг между ними настолько фундаментален, что простой “перевод” batch-кода в streaming почти всегда приводит к боли в production. Этот урок — про этот сдвиг.

К концу урока вы будете уметь различать, когда задача требует streaming, а когда вы делаете streaming просто потому, что это модно. Эта различимость важнее любого API.


Batch как мышление: данные конечны

В batch-обработке данные — это bounded dataset: конечный набор, который полностью существует в момент запуска job. Spark читает Parquet-файлы за вчерашний день, Hive обрабатывает таблицу. Job стартует, читает всё, преобразует, пишет, завершается.

DAG Scheduler в Spark: stages и barriers

Из этого следуют ключевые свойства batch:

  • Конечность — мы знаем границу датасета. SUM(amount) даст определённое число. ORDER BY работает — мы можем отсортировать всё в памяти.
  • Повторяемость — запуск job завтра на тех же данных даст тот же результат. Это критично для regression testing и аудита.
  • Латентность измеряется часами или сутками — batch-job стартует по cron, читает накопленные за период данные, выдаёт результат к утру.
  • Полный набор инструментов SQL — JOIN, GROUP BY, window functions, recursive CTEs работают без оговорок.

Batch — это то, как мы думаем о данных естественно. “Возьми все вчерашние транзакции, посчитай выручку по категориям” — естественное предложение. Тонкости появляются, когда мы говорим “посчитай выручку прямо сейчас, по мере прихода транзакций”.


Streaming как мышление: данные бесконечны

В stream processing данные — это unbounded stream: бесконечная последовательность событий, новые приходят в любой момент. Stream-job стартует и работает 24/7, обрабатывая события по мере их появления.

Из этого следуют принципиально другие свойства:

  • Бесконечность — мы никогда не знаем “всё”. SUM(amount) растёт всё время; ORDER BY невозможен в общем виде (мы не можем отсортировать бесконечность).
  • Время становится first-class — события приходят с timestamp; время “сейчас” отличается от времени “когда событие произошло”; обработка должна понимать оба.
  • Латентность измеряется секундами или миллисекундами — событие пришло, через 100 мс уже отражено в дашборде.
  • State становится явным — где batch держит intermediate result в shuffle файлах, streaming держит его в state backend на много дней.

Stream processing — это другая парадигма. Все привычные операции (JOIN, GROUP BY, агрегация) переосмыслены: они работают на потоке, и их результат — тоже поток (continuous query).


Главная разница: bounded vs unbounded

Batch DAG vs Stream DAG: одна задача — разные пайплайны
BATCH: bounded datasetBatch обрабатывает фиксированный объём данных. Job стартует, читает всё, завершается. Все операторы выполняются последовательно — следующий ждёт, пока предыдущий обработает весь датасет.

Read Parquet

Источник: статический файл, таблица. Spark или Hive читают весь файл/таблицу как RDD/DataFrame. Размер данных известен заранее.

Map

Map: применить функцию к каждой строке. В batch — параллельно по partitions, но всё происходит в течение одного job execution. После завершения map начинается shuffle.

Group + Sum

Group by + Aggregate: shuffle перераспределяет данные по ключу, затем агрегация. В batch — после этого этапа агрегаты ПОЛНЫЕ и финальные. Сохраняем в файл и выходим.

Write Parquet

Sink: записать финальный результат в Parquet, в таблицу. Job завершается. Все ресурсы (executors) освобождаются.
STREAMING: unbounded streamStreaming обрабатывает бесконечный поток. Job стартует и работает 24/7. Все операторы выполняются ОДНОВРЕМЕННО, событие проходит через всю pipeline на лету (pipelined execution).

Read Kafka

Источник: Kafka, Pulsar, Kinesis. События приходят бесконечно. Каждое событие обрабатывается отдельно, не дожидаясь следующих. Source постоянно poll'ит брокер.

Map

Map: применяется к каждому событию по одному, ПО МЕРЕ ПРИХОДА. Событие 1 уже на этапе Group, событие 2 на Map — pipelined parallelism.

Group + Sum (stateful)

Group + Sum: ОБНОВЛЯЕМЫЙ агрегат в state. Каждое новое событие апдейтит state и эмитит новое значение в down-stream. Финального результата НЕТ — он continuous.

Write Kafka

Sink: пишет апдейты continuously. Каждое изменение агрегата эмитится. Sink — Kafka, JDBC, файл, dashboard. Job НЕ завершается, продолжает работать.

Это не косметическое различие. Это два разных режима выполнения:

В batch DAG операторы выполняются последовательно по этапам (stages). Сначала весь Map, потом весь Shuffle, потом весь Aggregate. Между этапами — barrier: следующий этап стартует, когда предыдущий полностью завершён. В Spark это видно как этапы в Web UI: Stage 1, Stage 2, Stage 3.

В stream DAG операторы выполняются одновременно (pipelined). Источник поставляет события в Map, Map в Group, Group в Sink — все одновременно, конвейером. Событие N может быть в Group в то время, как событие N+1 ещё в Source. Это даёт streaming низкую end-to-end latency.


Где batch падает: примеры реальных задач

Несколько задач, которые batch решает “технически”, но streaming делает несоизмеримо лучше:

Real-time fraud detection. Транзакция пришла -> за 100 мс надо принять решение, fraud или нет. Batch-job, который раз в час смотрит транзакции, опоздает на час — карты уже использованы, деньги ушли. Streaming с stateful pattern matching и lookup в внешний risk-score сервис делает это за секунды.

Live dashboards. CEO открыл dashboard и хочет видеть выручку за сегодня прямо сейчас. Batch-job, который собирает дневной snapshot к утру следующего дня, не помогает. Streaming continuously обновляет агрегаты, дашборд видит изменения в реальном времени.

CDC (Change Data Capture). Реляционная база меняется тысячи раз в секунду. Batch-job, который читает таблицу каждые 5 минут, страдает от schema drift, потери изменений между чтениями, и невозможности отследить delete-операции. Streaming читает binlog/WAL и точно фиксирует каждое изменение.

CDC-фундаментал: что такое Change Data Capture

ML feature engineering для online prediction. Модель в production требует features прямо сейчас — “сколько раз пользователь кликнул за последние 5 минут”. Batch-job не подходит — features устаревают. Streaming материализует features в feature store в реальном времени.

Общий паттерн: задачи, где latency имеет ценность или где данные не имеют естественной границы по времени (например, событийные потоки), естественно решаются streaming. Задачи отчётности “за вчерашний день”, аналитики “за квартал” — это всё ещё batch territory.


Lambda и Kappa архитектуры

Когда компании впервые столкнулись с потребностью в real-time данных, они изобрели Lambda Architecture — параллельное использование batch и streaming.

Lambda и Kappa архитектуры — обзор

Lambda Architecture (Nathan Marz, 2011)

Lambda Architecture: batch + speed layer

Event Source (Kafka)

Источник событий — обычно Kafka или другой immutable log. Все события сохраняются для обоих layers одинаково.
фан-аут в два layer

Batch Layer

Batch Layer: ежедневный pre-computed pre-aggregates. Spark/Hive обрабатывает накопленные за день данные, пишет в Hive table или Parquet. Latency: сутки. Точность: 100% (полные данные).

Speed Layer

Speed Layer: real-time стрим, дающий приближённые real-time агрегаты. Storm/Spark Streaming/Flink. Latency: секунды. Точность: приближённая (без late events, без перерасчётов).
результат

Serving Layer

Serving Layer: объединяет batch и speed результаты. Запрос: 'дай агрегат за сегодня' — Cassandra/HBase отдаёт batch-результат за вчера + speed-результат за сегодня.

Идея: batch layer даёт точные результаты с задержкой суток; speed layer даёт быстрые приближённые для текущего дня. Serving layer объединяет их.

Боль Lambda: поддерживать ДВЕ pipelines с разной логикой. Каждая бизнес-логика реализована дважды: в Spark и в Storm. Изменение требования — править в двух местах. Тесты — раздельные. Bug fix в одном месте, забыли в другом — расхождение между batch и speed.

Kappa Architecture (Jay Kreps, 2014)

Jay Kreps (создатель Kafka) предложил: давайте уберём batch layer вовсе. Если stream processor умеет работать с историческими данными (replay из Kafka с offset=0), мы можем делать всё в одной streaming-pipeline.

Kappa Architecture: только streaming

Event Source (Kafka with long retention)

Источник: immutable log (Kafka). Retention — достаточно длинная, чтобы можно было replay для re-compute (часто месяцы или годы для критичных доменов).
один stream processor

Stream Processor (Flink)

Stream Processor: Flink, Kafka Streams. Один pipeline для всей логики. Для re-compute — стартуем второй экземпляр job с offset=0, прогоняем всю историю, переключаемся.
вывод

Serving Layer

Serving Layer: continuously обновляемые материализованные представления. Cassandra/Postgres/Elasticsearch. Никакой агрегации между batch и speed — всё считается одним pipeline.

Преимущества Kappa:

  • Одна pipeline — одна логика, один codebase.
  • Re-compute через replay — если правим логику, стартуем job v2 с offset=0, прогоняем историю, переключаем serving layer.
  • Меньше operational complexity — один тип системы (streaming) вместо двух.

Kappa стала возможной благодаря Kafka (длинная retention) и Flink (надёжный stateful streaming с exactly-once). В 2026 году большинство новых архитектур начинают с Kappa, а Lambda сохраняется в legacy системах.

NOTE

Kappa не значит “никогда не используем batch”. Batch остаётся для аналитики “вчерашних данных”, ad-hoc запросов через Trino/Presto, training ML-моделей. Kappa — это про operational pipelines, которые обслуживают live систему.


Когда выбирать batch, когда streaming

Не пытайтесь делать streaming везде. Это сложнее, требует больше дисциплины, и для многих задач избыточно.

Выбирайте batch, когда:

  • Latency требования — часы или сутки. “Отчёт за вчерашний день к 9:00 утра” — batch.
  • Данные имеют естественные границы. Месячный счёт за услуги — batch по концу месяца.
  • Логика сложна и активно меняется. Batch проще отлаживать на конечном датасете.
  • Точность критически важна, late events недопустимы. Финансовая отчётность для регулятора — batch с полной сверкой.
  • Стоимость инфраструктуры важнее latency. Batch дешевле, потому что использует ресурсы только во время run.

Выбирайте streaming, когда:

  • Latency требования — секунды или минуты. Live dashboards, real-time recommendations.
  • Данные не имеют естественных границ. Event streams (clicks, transactions, sensor data) — streaming natural.
  • Нужно реагировать на события (fraud detection, alerting). Batch не подходит — слишком поздно.
  • Нужна материализация always-fresh state. Feature stores для online ML.
  • CDC — streaming единственный корректный путь (нельзя терять delete-операции).

Часто правильный ответ — оба. Streaming для operational pipelines, batch для аналитики и backfills. Это и есть современная архитектура — Kappa для operational, batch для analytical, всё read’ит из одного immutable log (Kafka, Iceberg).


Попробуй сам

Возьмите 3 задачи из вашей текущей или прошлой работы:

  1. Какие из них вы решаете batch’ем? Подумайте — если бы latency требования были секунды, как бы это изменилось?
  2. Какие из них вы решаете streaming’ом? Подумайте — действительно ли latency настолько критична, или это unnecessary complexity?
  3. Найдите пример Lambda Architecture в legacy системе вашей компании. Можно ли его упростить до Kappa? Что мешает?

Ответы записывайте — мы будем возвращаться к этим примерам по ходу курса.

Проверка знанийKnowledge check
Команда разрабатывает live dashboard с показателями продаж за день. Они выбрали Spark Structured Streaming в micro-batch режиме с интервалом 10 минут. Через месяц жалобы: 'данные устаревают на 10 минут, CEO раздражён'. Это правильное использование streaming или нет, и какое решение?
ОтветAnswer
Это половинчатое решение. Micro-batch с интервалом 10 минут — это batch с маленьким окном, а не настоящий streaming. Latency складывается из: max(интервал micro-batch) + время обработки = 10-12 минут. Если требование — latency секунды, нужен true streaming (Flink с continuous processing или Spark continuous processing mode). Если требование — latency минуты, текущее решение приемлемо, но интервал стоит уменьшить до 1-2 минут. Часто компании выбирают micro-batch из-за familiarity со Spark, не понимая trade-offs. True streaming (Flink) для real-time dashboards решает задачу за секунды, ценой более сложного state management и обязательного event time mode.

Проверьте понимание

Результат: 0 из 0
Концептуальный
Вопрос 1 из 4. Главное архитектурное различие между batch DAG и stream DAG в плане выполнения операторов — это:

Закончили урок?

Отметьте его как пройденный, чтобы отслеживать свой прогресс

Войдите чтобы оценить урок

Прогресс модуля
0 из 4