Зачем нужен Spark и как он работает
Что проверяют
Понимаете ли вы, откуда берётся ускорение и когда Spark вообще нужен. Ответ «он быстрый, потому что в памяти» считается поверхностным. Следом спрашивают про ленивые вычисления, shuffle и разницу между transformation и action.
Как отвечать
Зачем: обработка данных, которые не помещаются на одну машину или обрабатываются на ней слишком долго. Spark даёт один движок для батчевого ETL, SQL-аналитики, потоков (Structured Streaming) и распределённого ML (pyspark.ml), код пишется на Python, Scala, Java или SQL.
Как устроен:
- драйвер и executors: драйвер строит план и раздаёт задачи, executors на узлах выполняют их над своими партициями. Ресурсы выделяет менеджер кластера: YARN, Kubernetes или standalone;
- ленивость: трансформации (
filter,select,join,groupBy) только достраивают план, вычисление запускает действие:count,collect,write; - оптимизатор: DataFrame API и SQL проходят через Catalyst, который опускает фильтры к источнику и выбирает тип join. Adaptive Query Execution (включён по умолчанию с версии 3.2) правит план по фактической статистике, например склеивает мелкие партиции;
- стадии и shuffle: job делится на stages по границам широких зависимостей. Shuffle, перераспределение данных по ключу между узлами при
groupByилиjoin, самая дорогая часть, и оптимизация в основном про его сокращение; - отказоустойчивость: потерянная партиция пересчитывается по lineage, цепочке трансформаций от источника;
- память: промежуточный результат кешируется через
cache()илиpersist(), в этом выигрыш перед MapReduce, который пишет каждый шаг на диск.
Для ML назовите границы: Spark хорош для подготовки фичей на терабайтах, а небольшую модель часто быстрее обучить на одной машине в pandas и scikit-learn.
Где спотыкаются
Называют RDD основным API. В современном коде работают с DataFrame и SQL, к RDD спускаются только при необходимости.
Вызывают collect() или toPandas() на большом датафрейме и роняют драйвер по памяти.
Пишут Python UDF там, где хватает встроенных функций из pyspark.sql.functions. Внутрь UDF оптимизатор не заглядывает, а данные гоняются между JVM и Python.