Продолжаем серию статей про языки программирования, которые используются в «Криптоните». В этой части наш ведущий инженер департамента разработки Михаил Кузнецов расскажет об особенностях и применении Spark, его плюсах и минусах, о тонкостях изучения фреймворка, а также поделится идеями для pet-проекта и полезными ссылками. Предыдущие части про Rust, Scala и JavaScript. Начнём с того, что Spark – это фреймворк, который целиком написан на Scala. Но высокоуровневое API он предоставляет также и на Python, Java и т.д. Хоть Java и Scala равны по скорости и функционалу, пользоваться фреймворком всё равно гораздо удобнее и лаконичнее на Scala. На остальных языках может урезаться функционал и скорость обработки.  Spark был создан для обработки данных. Есть так называемый процесс ETL – extract, transform, load (извлечение, преобразование, загрузка) – эти три задачи Spark и закрывает. Он берёт данные из источника, преобразует их (чистит, обогащает, соединяет…), а результат подаёт в приёмник, например — в базу данных. То есть выполняется процессинг данных.  Особенность Spark в том, что другого такого фреймворка нет в принципе. Flink, Apache NiFi и другие инструменты закрывают не все задачи. Лично моё мнение – Spark на голову выше их всех. Он уникален, широко распространён и де-факто является стандартом индустрии обработки больших данных.  Spark используется везде, где требуется обработка каких-либо данных в больших объёмах, которые не вмещаются на один сервер. Сюда подходит всё, что угодно – данные с различных датчиков (IoT), маркетинговые данные (в т.ч. кликстримы), погодная аналитика, здравоохранение, банки, анализ сигналов от спутника…  в общем — все направления с большим количеством данных. Spark подойдёт вам, если вы любите копаться с данными. Я вот люблю😊 Например, в «Криптоните» я занимаюсь проектированием dataflow и разработкой на его основе Spark job, пайплайнов NiFi, дагов Airflow. А ещё я пишу кастомные компоненты для этих инструментов и yaml, касающиеся работы пайплайнов + провожу ресерч новых дата-инструментов и пишу PoC. Плюсы: 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, и часть этого кода будет выполняться на драйвере, а часть – отправлена на экзекьютеры. Надо хорошо понимать, какие именно части полетят на экзекьютеры, как они будут работать. От этого зависит отработает ли джоба вообще, какое будет потребление ресурсов, сколько это займёт времени... Но это скилл, который можно наработать, он придёт с опытом. У Spark большое комьюнити: и русско-, и англоязычное. Без помощи вы точно не останетесь. В Telegram есть довольно много каналов, посвящённых обработке данных, в том числе есть группа конкретно про Spark (первая в списке ниже): https://t.me/moscowspark;  https://t.me/dataengineering_chat_ru; https://t.me/hadoopusers; https://t.me/rockyourdata;   https://t.me/nifiusers;   https://t.me/clickhouse_ru; https://t.me/ruairflow. Из англоязычных ресурсов я бы рекомендовал YouTube-канал «Databricks». Его ведут ребята, которые совершенствуют Spark, выкладывают презентации и видео c «внутрянкой», которую больше нигде не найдёшь. Если хочется «под капот», то этот канал как раз подойдёт. Начальный уровень 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 и т.д.). В Data Engineering самый классический и базовый вариант для pet-проекта – это ETL-процесс. Берём откуда-то данные, как-то их обрабатываем и куда-то сохраняем. Это можно довести до сумасшедшей сложности. Данные можно брать из простых источников (например, CSV-файла), а можно взять из Kafka в формате avro или protobuf. Главное – понять для себя логику, чтобы в итоге сформировать законченный процесс «берём-преобразуем-сохраняем».  В Data Engineering довольно много направлений и всегда можно выбрать, чем хотелось бы заниматься. Можно по большей части кодить на Spark, а можно «эскуэлить». Вот мы из Spark взяли что-то из Kafka, положили в ClickHouse, и там что-то «повертели» SQL’ем. Это пайплайн, который покажет твоё умение работать с тремя инструментами. К этому можно добавить планировщик типа Airflow, или «прикрутить» какой-нибудь дашбординг. Я, например, как-то глубоко копался «под капотом» Spark и написал собственный data source, а ещё писал нативные UDF. Но это всё проекты, с которыми разработчики навряд ли столкнутся на работе. Мне просто было интересно разобраться во «внутрянке», а ещё мне важно понимать, как работает инструмент до винтика.