Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Особенности разработки Flink джобов на Scala

Особенности разработки Flink джобов на Scala

Apache Flink, Scala API

Avatar for Alexey Novakov

Alexey Novakov

September 14, 2025
Tweet

More Decks by Alexey Novakov

Other Decks in Programming

Transcript

  1. • Краткий обзор Apache Flink • Примеры использования • Flink

    Scala API и его замена • Преимущества Scala при работе с Flink • Как разрабатывать Flink джобы на Scala • Вопросы и Ответы Содержание 2
  2. 60 PB данных в день - Netflix > 1800 GitHub

    со-авторов Что такое Apache Flink? 2014 в Apache Incubator. В 2016 1.0 версия < 100ms задержка (latency) Кластерное приложение для обработки потоковых данных в реальном времени Режимы: streaming и batch Часто используется вместе с Kafka Быстрее чем “Мощнее*” чем Kafka Streams (Flink App vs. KS app) 4
  3. Применение в индустрии Интеграция Данных ETL/ELT, Озера данных, Транзакционные Логи

    (CDC), Потоковый Lakehouse Аналитика данных в реальном времени Stream/Batch SQL, BI отчеты, Mat. Views Сложная событийная обработка (CEP*) фин. мониторинг, обр. транзакций, кибербезопасность (EDR), сенсоры на конвейерах ( IoT) AI и ML Обучение моделей, генерация рекомендаций, ML feature store *Complex Event Processing 5
  4. Потоковая Обработка с Состоянием Вычисления Вычисления Поток (источник) Статичные данные

    (источник) локальное состояние локальное состояние Вычисления Вычисления локальное состояние Хранилище (приемник) Поток (приемник) Трансформация Таймер единая распределенная программа 6
  5. Пример на DataStream API val lines = env.fromSource(KafkaSource.builder[String]()....) val events

    = lines.map(parse) // def parse(s: String): String = ??? val stats = stream .keyBy("sensor") .window(TumblingProcessingTimeWindows.of(Time.seconds(5))) .aggregate(MyAggregationFunction()) stats.sinkTo(MyAlertSink(path)) Источник Трансформация Группировка Агрегация Приемник Логический поток данных 8
  6. Применение в бизнесе ING банк: обнаружение мошенничества (Fraud Detection) https://www.ververica.com/blog/real-time-fraud-detection-ing-bank-apache-flink,

    Платформа обработка потоковых данных: https://smartdataconf.ru/archive/2024/talks/da48c7cc0108449c89ad36cefa64777d/ Lyft такси-сервис: определение времени подбора клиента, динамическая цена, генерация ML св-ва для обнаружения мошенничества. https://www.alibabacloud.com/blog/lyfts-large-scale-flink-based-near-real-time-data-analytics-pla tform_596674 Netflix: персонализация, рекомендации, мониторинг качества видеопотока и доставки контента, мониторинг сервисов Alibaba: электронная коммерция, интеграция данных, аналитика в реальном времени. 10
  7. Сценарии с Flink Custom Web App Сценарии: look up Apache

    Paimon 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 Lakehouse CDC 11
  8. Flink vs. Scala версии Flink v. < 1.15 Flink v.

    [1.15 … 2.0) Flink v. [2.x … Apache Flink Scala API: только Scala 2.12 Scala 2.13 или 3.x: - Через Java flink4s flink-extended/ flink-scala-api Самописная сериализация для Scala типов Community Scala API: Scala релиз 2.12 - 2016 релиз 2.13 - 2019 релиз 3.0 - 2021 13
  9. Как использовать Scala 2.13/3 в Flink - Удалить flink-scala JAR

    из Flink дистрибутива: $ rm flink-dist/lib/flink-scala* - Использовать Java API для своего Flink приложения: @main def job = val env = StreamExecutionEnvironment.getExecutionEnvironment env .fromElements(1, 2, 3, 4, 5, 6) .filter(_ % 2 == 1).map(i => i * i).print() env.execute() - Реализовать сериализаторы для используемых Scala типов 14
  10. Замена Apache Flink Scala API flink-extended/flink-scala-api: - GitHub форк Flink

    Scala изначально созданный в Findify (спасибо - Роман Г.) - поддерживает Scala 2.13 и 3.x Как мигрировать: // оригинальный API import import org.apache.flink.streaming.api.scala.* // flink-scapa-api imports import org.apache.flinkx.api.* import org.apache.flinkx.api.serializers.* Было: Стало: 15
  11. Миграция Состояния: Flink State Processor API State Processor API Job

    на Scala 2.12 State Processor API Job на Scala 3 если хотим продолжить использовать текущее состояние: одноразовые приложения Scala 2.12 Savepoint (Apache) Pojo/Kryo Savepoint (Apache) Scala 3 Savepoint (Community) (1) (2) 16
  12. 1. Автоматическое выведение Flink сериализаторов во время компиляции (просто добавляем

    импорт): a. базовые типы Scala b. ADT во время компиляции 2. Сериализация без использования Java Reflection во время исполнения (Magnolia) 3. Без скрытого переключения на Kryo сериализаторы (ошибка компиляции) 4. Расширяемость сериализаторов для глубоко- вложенных типов через Type Classes Почему Scala? преимущества в сериализации: 18
  13. - Меньше объем кода! Python: нужно создать TypeInformation вручную и

    передавать всюду по коду Почему Scala? (2) # compute word count ds = ds.map(id_to_word) \ .map(lambda i: (i, 1), output_type=Types.TUPLE([Types.STRING(), Types.INT()])) \ .key_by(lambda i: i[0]) \ 19
  14. import org.apache.flinkx.api.serializers.* case class Foo(x: Int): def inc(a: Int) =

    copy(x = x + a) // явное определение для кэширования // если не определено, тогда выводится автоматически given fooTypeInfo: TypeInformation[Foo] = deriveTypeInformation[Foo] env .fromElements(Foo( 1),Foo(2),Foo(3)) .map(x => x.inc( 1)) // передано как given .map(x => x.inc( 2)) // снова, без повторного выведения Выведение Сериализаторов 20
  15. Неизменность по умолчанию (ObjectReuse) - Scala Case Class -> immutable,

    почти всегда (var) env.getConfig.enableObjectReuse - > меньше времени на передачу данных - Также актуально для HashMapStateBackend case class Transaction( accountId: Long, timestamp: Long, amount: Double, loc: String = "" ) 21
  16. Без автоперехода на Kryo import org.apache.flinkx.api.serializers.* env .fromElements( "To", "be",

    "or", "not", "to", "be") .map(_.toLowerCase) .map(w => SomeWord( Timestamp(System.currentTimeMillis), w, 1) ) [error] |No given instance of type org.apache.flink.api.common.typeinfo .TypeInformation[java.sql.Timestamp] was found. source: https://flink.apache.org/2020/04/15/flink-serialization-tuning-vol.-1-choosing-your-serializer-if-you-can/ 22
  17. - Сборка fat JAR через: - SBT - Scala-CLI -

    Mill - Для новой версией Scala, заменить flink-scala*.jar в flink/lib на: - scala-library-2.13.x.jar - scala-library_3-3.y.z.jar (опционально) - flink-scala-api-2_3-a.b.c.jar (из flinkextended) - Для моделей данных используй Case Classes / Enums / ADTs Отличия от Java или Python 25
  18. Flink Job - Шаблон > sbt new novakov-alexey/flink-scala-api.g8 name [My

    Flink Scala Project]: new-flink-app flinkVersion [1.20.1]: // press enter to use 1.20.1 Template applied in /Users/myhome/dev/git/./new-flink-app new-flink-app ├── build.sbt ├── project │ └── build.properties └── src └── main └── scala └── com └── example └── WordCount.scala 26
  19. scala-cli //> using scala "3" //> using dep "org.apache.flink:flink-table-api-java:1.15.4" import

    org.apache.flink.table.functions.ScalarFunction import org.apache.flink.table.annotation.DataTypeHint import java.util.{Map as JMap} class MultisetToString extends ScalarFunction: def eval( @DataTypeHint("MULTISET<INT>") mset: JMap[ Integer, String ] ) = mset.toString scala-cli package --jvm 11 \ multisetToString.scala \ -o udfs.jar \ --library -f один файл, одна команда пакует UDF в JAR файл 27
  20. Apache Flink Kubernetes Operator - Поддерживает Application или Session mode

    - Прекрасно подходит для управлениями Flink приложениями в продакшене - Позволяет настроить и развернуть Flink дистрибутив через - K8s CRDs - Docker образ для Flink JM & TM apiVersion: flink.apache.org/v1beta1 kind: FlinkDeployment spec: ………… job: jarURI: local:///opt/flink/usrlib/word-count-job.jar entryClass: WordCount 29
  21. # добавляем новую Scala и новый Scala API чтобы не

    паковать в fat JAR ADD --chown=flink --chmod=644 scala3-library_3-3.7.1.jar $FLINK_HOME/lib/ ADD --chown=flink --chmod=644 scala-library-2.13.16.jar $FLINK_HOME/lib/ ADD --chown=flink --chmod=644 flink-scala-api-2_3-1.2.8.jar $FLINK_HOME/lib/ Как развернуть Scala 3 Job через Flink Operator FROM flink:2.0.0 # удаляем старый Scala модуль RUN rm $FLINK_HOME/lib/flink-scala*.jar - Собираем свой Docker Job образ # добавляем свой Job JAR COPY word-count-job.jar /opt/flink/usrlib/ 30
  22. В Итоге - Основное отличие в разработке на Scala это

    инструментарий - Более “функциональный” и менее “развесистый” код - Сериализация без головной боли (auto-derivation) - Доступ к самым новым возможностям Scala 3 Попробуй реализовать свой следующий Flink job на flink-scala-api! Пример конвертации Scala Savepoint: 32 Релиз 1.15 о Scala-free Extended Flink Scala API
  23. 33 Пример конвертации savepoint: - https://ververica.zendesk.com/hc/en-us/articles/10627965111068-How-to-migrate-a-savepoint-created-using-Apache- Flink-Scala-API-to-another-format - Релиз 1.15

    о Scala-free - :https://flink.apache.org/2022/02/22/scala-free-in-one-fifteen/ - https://github.com/flink-extended/flink-scala-api Extended Flink Scala API