Открыть сервис

DataStream API

DataStream API — это программный интерфейс приложения (API), предоставляемый фреймворками для обработки потоковых данных (например, Apache Flink), который позволяет разработчикам создавать приложения для обработки неограниченных потоков данных в реальном времени. DataStream API обеспечивает декларативное и функциональное описание логики преобразования, фильтрации, агрегации и анализа данных, поступающих непрерывно, в отличие от пакетной обработки, где данные обрабатываются статическими наборами.

История

Концепция потоковой обработки данных возникла как ответ на потребность в анализе информации в реальном времени, когда задержки, присущие пакетной обработке, стали критическими. Ранние системы, такие как Apache Storm (2011 год), предоставляли низкоуровневые примитивы для обработки потоков, но требовали от разработчиков ручного управления состоянием и гарантиями доставки.

Развитие DataStream API связано с проектом Apache Flink, который изначально проектировался как система для потоковой обработки. В 2015 году Flink представил DataStream API как основной интерфейс для работы с бесконечными потоками. Ключевым нововведением стала концепция «обработки на основе событий» (event-time processing) и точные семантики доставки (exactly-once semantics). В последующие годы API был расширен: появились поддержка оконных функций (windowing), сложных операций с состоянием (stateful processing) и интеграция с различными источниками и приемниками данных (Apache Kafka, Amazon Kinesis, Google Pub/Sub и другие).

Ключевые концепции

Поток данных (DataStream)

Основной абстракцией в DataStream API является DataStream — это последовательность записей (событий), неограниченная во времени. Каждая запись представляет собой элемент данных, который может быть примитивным типом, кортежем, объектом класса или любым сериализуемым типом. Поток может быть:

  • Неограниченным (unbounded): данные поступают непрерывно, и конец потока не определен.
  • Ограниченным (bounded): данные имеют фиксированный объем, что позволяет обрабатывать их как пакет (batch), используя тот же API.

Операции преобразования

DataStream API предоставляет набор операций, которые применяются к потоку и возвращают новый поток. Основные типы операций:

  • Однозначные (map, flatMap): преобразуют каждый элемент потока в один или несколько новых элементов.
  • Фильтрация (filter): пропускает элементы, удовлетворяющие заданному условию.
  • Агрегация (keyBy, sum, min, max): группирует элементы по ключу и применяет агрегатную функцию.
  • Соединение (join, coGroup): объединяет два потока по ключу, часто с использованием окон.

Окна (Windows)

Поскольку неограниченный поток не имеет естественных границ, для выполнения агрегаций (например, подсчет количества событий за последние 5 минут) используются окна. DataStream API поддерживает несколько типов окон:

  • Окна по времени (tumbling, sliding, session windows): основаны на временных метках событий (event time) или времени обработки (processing time).
  • Окна по количеству (count windows): срабатывают после накопления заданного числа элементов.
  • Глобальные окна (global windows): все элементы потока считаются одним окном, обычно используются с пользовательскими триггерами.

Состояние (State)

Для поддержки операций, требующих запоминания данных между событиями (например, для вычисления скользящего среднего), DataStream API предоставляет механизмы управления состоянием. Состояние может быть:

  • Управляемым (managed state): автоматически управляется фреймворком, поддерживает чекпоинты (checkpoints) для отказоустойчивости.
  • Операторным (operator state): привязано к одному оператору (например, для хранения буфера).
  • Ключевым (keyed state): привязано к конкретному ключу, доступно только в операциях после keyBy.

Время и водяные знаки (Watermarks)

DataStream API поддерживает три концепции времени:

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

Для обработки событий, которые могут приходить с задержкой (out-of-order events), используются водяные знаки — специальные метки, которые сигнализируют, что все события с временем до определенного порога уже поступили.

Архитектура и реализация

В Apache Flink

DataStream API является частью основного стека Apache Flink. Приложение, написанное с использованием DataStream API, компилируется в граф выполнения (execution graph), который состоит из операторов (operators) и соединений между ними. Этот граф затем распределяется по узлам кластера для параллельного выполнения.

Ключевые компоненты реализации:

  • JobManager: отвечает за координацию, планирование и чекпоинты.
  • TaskManager: выполняет операторы в параллельных подзадачах.
  • CheckpointCoordinator: периодически сохраняет состояние приложения для обеспечения отказоустойчивости.

В других фреймворках

Хотя DataStream API наиболее тесно ассоциируется с Apache Flink, аналогичные концепции реализованы в других системах:

  • Apache Spark Structured Streaming: предоставляет DataStreamReader и DataStreamWriter, но использует микропакетную архитектуру (micro-batch).
  • Apache Beam: унифицированный API, который позволяет выполнять потоковые и пакетные задачи на разных бэкендах (Flink, Spark, Google Dataflow).
  • Kafka Streams: библиотека для обработки потоков, встроенная в Apache Kafka, с собственной реализацией потокового API.

Применение

DataStream API используется в сценариях, где требуется низкая задержка и обработка данных в реальном времени:

  • Мониторинг и аналитика: анализ логов серверов, мониторинг сетевого трафика, обнаружение аномалий.
  • Финансовые системы: обработка транзакций в реальном времени, выявление мошенничества, расчет рисков.
  • Интернет вещей (IoT): обработка данных с датчиков, управление устройствами в реальном времени.
  • Рекомендательные системы: обновление рекомендаций на основе поведения пользователей в реальном времени.
  • ETL-процессы: непрерывная загрузка и трансформация данных из источников в хранилища.

Преимущества и ограничения

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

Ограничения

  • Сложность разработки: требует понимания концепций времени, состояния и водяных знаков.
  • Ресурсоемкость: поддержка состояния и чекпоинтов может потреблять значительные объемы памяти и дискового пространства.
  • Не подходит для всех задач: для задач, требующих сложных многоэтапных запросов с произвольными соединениями, могут быть более эффективны системы пакетной обработки.

Пример использования

Ниже приведен упрощенный пример на Java (Apache Flink), демонстрирующий подсчет количества слов в потоке текстовых строк, поступающих из Apache Kafka:

```java StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();

DataStream<String> text = env.addSource(new FlinkKafkaConsumer<>("input-topic", new SimpleStringSchema(), properties));

DataStream<Tuple2<String, Integer>> wordCounts = text .flatMap((String line, Collector<Tuple2<String, Integer>> out) -> { for (String word : line.split(" ")) { out.collect(new Tuple2<>(word, 1)); } }) .keyBy(value -> value.f0) .window(TumblingProcessingTimeWindows.of(Time.minutes(1))) .sum(1);

wordCounts.addSink(new FlinkKafkaProducer<>("output-topic", new SimpleStringSchema(), properties));

env.execute("Word Count Example"); ```

Сравнение с другими подходами

ХарактеристикаDataStream API (Flink)Spark Structured StreamingKafka Streams
Модель обработкиНативная потоковаяМикропакетная (микро-батч)Нативная потоковая
Гарантии доставкиExactly-onceExactly-onceExactly-once
Управление состояниемВстроенное, с чекпоинтамиВстроенное, с чекпоинтамиВстроенное, с чангилогами
ЯзыкиJava, Scala, PythonJava, Scala, Python, RJava, Scala
Интеграция с KafkaЧерез коннекторЧерез коннекторНативная

Источники

  • Apache Flink Documentation: DataStream API
  • «Stream Processing with Apache Flink» by Fabian Hueske and Vasiliki Kalavri
  • Apache Beam Documentation: Programming Guide
  • «Kafka Streams: The Definitive Guide» by Bill Bejeck

BFOmetr — база данных и аналитика по компаниям России.

На главную BFOmetr →