Продолжаем серию статей про языки программирования, которые используются в «Криптоните». В этой части наш ведущий инженер департамента разработки Михаил Кузнецов расскажет об особенностях и применении Spark, его плюсах и минусах, о тонкостях изучения фреймворка, а также поделится идеями для pet-проекта и полезными ссылками.

Предыдущие части про Rust, Scala и JavaScript.

1. Особенности

Начнём с того, что Spark – это фреймворк, который целиком написан на Scala. Но высокоуровневое API он предоставляет также и на Python, Java и т.д. Хоть Java и Scala равны по скорости и функционалу, пользоваться фреймворком всё равно гораздо удобнее и лаконичнее на Scala. На остальных языках может урезаться функционал и скорость обработки.

Spark был создан для обработки данных. Есть так называемый процесс ETL – extract, transform, load (извлечение, преобразование, загрузка) – эти три задачи Spark и закрывает. Он берёт данные из источника, преобразует их (чистит, обогащает, соединяет…), а результат подаёт в приёмник, например — в базу данных. То есть выполняется процессинг данных.

Особенность Spark в том, что другого такого фреймворка нет в принципе. Flink, Apache NiFi и другие инструменты закрывают не все задачи. Лично моё мнение – Spark на голову выше их всех. Он уникален, широко распространён и де-факто является стандартом индустрии обработки больших данных.

2. Где используется

Spark используется везде, где требуется обработка каких-либо данных в больших объёмах, которые не вмещаются на один сервер. Сюда подходит всё, что угодно – данные с различных датчиков (IoT), маркетинговые данные (в т.ч. кликстримы), погодная аналитика, здравоохранение, банки, анализ сигналов от спутника…  в общем — все направления с большим количеством данных.

Spark подойдёт вам, если вы любите копаться с данными. Я вот люблю???? Например, в «Криптоните» я занимаюсь проектированием dataflow и разработкой на его основе Spark job, пайплайнов NiFi, дагов Airflow. А ещё я пишу кастомные компоненты для этих инструментов и yaml, касающиеся работы пайплайнов + провожу ресерч новых дата-инструментов и пишу PoC.

3. Плюсы и минусы

Плюсы:

1. Огромное количество встроенных источников, откуда мы берём данные.

2. Система плагинов.  Через определение своих datasource мы можем, например, написать алгоритм обработки определённого вида файла, если до нас никто этого не сделал.

3. Довольно простой API, а также удобный и информативный UI. Можно «тыкать» по кнопкам и смотреть, куда бегут байты, какой сейчас стейдж, сколько уже обработано и т.д.

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

5. Batch-обработка. Например, если «набежало» много данных за день, он автоматически может обработать их ночью.

6. Spark Streaming. Стриминговая обработка позволяет бизнесу получать агрегаты данных максимально близко к реальному времени.

7. Большой набор как встроенных, так и кастомных коннекторов для различных источников.

8. Объём обрабатываемых данных зависит только от ресурсов кластера. Горизонтальное масштабирование всегда удобнее и дешевле вертикального.

Минусы:

Поскольку Spark – это продукт JVM экосистемы, получаем все минусы, ей присущие.

1. Если в параметрах экзекьюторов ты указал недостаточно памяти для обработки конкретного датасета – получишь Out Of Memory Error (OOM). Потребление памяти на экзекьютерах при обработке больших датасетов огромное. Необходимо много ресурсов (оперативки и быстрых SSD).

2. Если мы говорим про стриминг, то надо понимать, что в Spark он микробатчевый и работает не так как во Flink, где каждое событие обрабатывается, как только «прилетает». Здесь логика другая: «прилетело» одно событие, второе, третье…  Они накапливаются и уходят в обработку не сразу, а когда их соберётся указанное количество. Соответственно, latency из-за этого страдает.

3. Latency также страдает из-за garbage collection. Никто не знает, в какой момент GC решит собрать мусор. Это так называемый «stop-the-world», когда все процессы останавливаются.

4. Не уверен, что это минус, но всё же – придётся перестраивать мышление на распределённую обработку. Мы пишем код на Spark, и часть этого кода будет выполняться на драйвере, а часть – отправлена на экзекьютеры. Надо хорошо понимать, какие именно части полетят на экзекьютеры, как они будут работать. От этого зависит отработает ли джоба вообще, какое будет потребление ресурсов, сколько это займёт времени... Но это скилл, который можно наработать, он придёт с опытом.

4. Комьюнити

У Spark большое комьюнити: и русско-, и англоязычное. Без помощи вы точно не останетесь.

В Telegram есть довольно много каналов, посвящённых обработке данных, в том числе есть группа конкретно про Spark (первая в списке ниже):

Из англоязычных ресурсов я бы рекомендовал YouTube-канал «Databricks». Его ведут ребята, которые совершенствуют Spark, выкладывают презентации и видео c «внутрянкой», которую больше нигде не найдёшь. Если хочется «под капот», то этот канал как раз подойдёт.

5. Обучение

Начальный уровень Spark вполне реально освоить самостоятельно. Вместо вводного курса я бы попросил у руководства неделю-другую, чтобы прочитать статьи на Medium (сейчас только с VPN) и Habr, посмотреть видеокурсы на Youtube, а если хватает времени – прочитать книги по Spark от O'Reilly и прогнать примеры из них.

Считаю, что на большинстве распиаренных курсах по Spark вас ничему толком не научат. Основной объём обучающих материалов в них нацелен на обработку данных на Python, потому что там всё намного проще. Когда дело касается Scala, с материалами прямо беда. Я знаю буквально пару хороших специализированных курсов, которые позволяют «залезть под капот» именно на Scala. Вот примеры: https://newprolab.com/, https://rockthejvm.com/.

Точка входа в Spark – это базовое знание Scala в её функциональном виде. Это коллекции и понимание операций над ними, такие как map, flatMap, foreach. Где-то могут пригодиться implicit'ы. Многие пугаются языка, его сочетания парадигм, но все сложные моменты в Scala начинаются с асинхронности, а это в Spark нужно довольно редко (например, это может потребоваться в foreachBatch стриминге). Так что «скаловая» часть, которую придётся изучить, небольшая и дружелюбная.

Помимо знания Spark, важно понимать концепции работы других инструментов, и какой класс задач они решают. Например, знать, чем Flink Streaming отличается от Spark Streaming, зачем нужна Kafka или различные виды NoSQL-баз (Cassandra, Neo4J и т.д.).

6. Pet-проекты

В Data Engineering самый классический и базовый вариант для pet-проекта – это ETL-процесс. Берём откуда-то данные, как-то их обрабатываем и куда-то сохраняем. Это можно довести до сумасшедшей сложности. Данные можно брать из простых источников (например, CSV-файла), а можно взять из Kafka в формате avro или protobuf. Главное – понять для себя логику, чтобы в итоге сформировать законченный процесс «берём-преобразуем-сохраняем».

В Data Engineering довольно много направлений и всегда можно выбрать, чем хотелось бы заниматься. Можно по большей части кодить на Spark, а можно «эскуэлить». Вот мы из Spark взяли что-то из Kafka, положили в ClickHouse, и там что-то «повертели» SQL’ем. Это пайплайн, который покажет твоё умение работать с тремя инструментами. К этому можно добавить планировщик типа Airflow, или «прикрутить» какой-нибудь дашбординг.

Я, например, как-то глубоко копался «под капотом» Spark и написал собственный data source, а ещё писал нативные UDF. Но это всё проекты, с которыми разработчики навряд ли столкнутся на работе. Мне просто было интересно разобраться во «внутрянке», а ещё мне важно понимать, как работает инструмент до винтика.

Комментарии (4)


  1. 18741878
    15.08.2023 07:22
    +2

    "Хоть Java и Scala равны по скорости и функционалу, пользоваться фреймворком всё равно гораздо удобнее и лаконичнее на Scala"

    Если Bigdata - основное направление профессиональной деятельности, то спорить не буду - надо учить Scala. Но зачастую такого специалиста в штате нет, а данные обрабатывать надо. Отдавать работу на сторону тоже не вариант - данные зачастую весьма чувствительные. Маскировать их - лишняя морока далеко не всегда оправданная по времени и ресурсам. Но поскольку специалистов по Java на порядок (как минимум) больше, чем на Scala, то Java - отличный кандидат. Может быть, какие-то доли %% производительности по сравнению со Scala и будут потеряны, но зато это с лихвой компенсируется понятностью кода и более низким порогом входа. Еще плюс - для Java существует мега-количество надежных и распространенных фреймворков (чего далеко бегать - Spring). Нет проблем совместить обработку бигдаты с возможностями таких фреймворков. Для Scala инфраструктура куда беднее, а "женить" в одном проекте Scala и Java - так себе удовольствие.

    Все это, разумеется, сугубо IMHO - без наезда и обид. На собственном опыте и ничего более


    1. mrk-andreev
      15.08.2023 07:22
      +3

      Нет проблем совместить обработку бигдаты с возможностями таких фреймворков.

      Я понимаю, что есть доклад про использование Spring+Spark (https://www.youtube.com/watch?v=XLSQJQjmFFw ), но это скорее экзотика, чем общепринятая практика.

      Но поскольку специалистов по Java на порядок (как минимум) больше, чем на Scala, то Java - отличный кандидат. Может быть, какие-то доли %% производительности по сравнению со Scala и будут потеряны, но зато это с лихвой компенсируется понятностью кода и более низким порогом входа.

      На самом деле от разработчика в случае Spark не требуется уметь во все особенности Scala, по факту это лишь DSL для Spark. При этом разработчиков и вообще экспертизы сообщества гораздо больше для пары Scala+Spark, чем для Java+Spark.

      Обычно выбор стоит между Scala или Python для Spark. Первый язык предпочитают в случае доминирования в команде DE (Data engineer-ов): на Scala гораздо проще отлаживать код, проще читать сообщения об ошибках; в случае DS (Data science) ориентированной команды выбирают Python из-за популярности этого языка в индустрии анализа данных: большинство библиотек и как следствие проектов используют именно этот язык. Получается, что проще поддерживать проект, который полностью написан на одном языке, чем проект, который использует сразу два языка.

      Безусловно, все зависит от контекста. И может быть именно в вашем случае нужен Kotlin / Java / Scala (сразу или по-отдельности, или в произвольных пропорциях).


      1. sshikov
        15.08.2023 07:22
        +2

        но это скорее экзотика, чем общепринятая практика.

        Да никакой экзотики. У нас вот примерно половина проектов спринг, а вторая без него. Просто не особо-то оно в спарке в его типичном применении нужно (впрочем, это такое же личное частное мнение, как и ваше).


  1. mikegordan
    15.08.2023 07:22

    Центром всех стриминговых являются окно, у Спарта проблемы как раз с этим. Советую начать с Flink , т.к. там у окон можно легко переопределять триггеры, из коробки полно разных типов. 3 уровня абстракции api и для кода и для SQL style. Самое главное что при стриминге по event watermark через тригеры заводятся таймеры на закрытия. А например у Спарк такого нету, чеки идут только на пришедшее новое сообщения. )