Какие оптимизации проводит Spark
Что проверяют
Понимаете ли вы, что происходит между вашим кодом на DataFrame и задачами на executors, и умеете ли этим управлять. Следом часто просят прочитать план из explain() или объяснить, почему конкретный джоин оказался медленным.
Как отвечать
Основа всех оптимизаций это ленивое вычисление: трансформации только строят план, а работа начинается на действии вроде count() или write. Поэтому Spark видит запрос целиком и может его переписать.
- Catalyst: оптимизатор Spark SQL и DataFrame API. Анализирует запрос, упрощает логический план (проталкивание фильтров, отсечение ненужных колонок, свёртка констант) и выбирает физический;
- pushdown в источник: для Parquet и ORC фильтр уходит в чтение файла, лишние row groups и колонки не читаются вовсе;
- Tungsten: бинарный формат строк вне объектов JVM, меньше нагрузки на GC, и whole-stage codegen, который склеивает цепочку операторов в один сгенерированный метод;
- выбор джоина: если одна сторона меньше
spark.sql.autoBroadcastJoinThreshold(по умолчанию 10 МБ), её рассылают на все узлы и shuffle не нужен, иначе обычно sort-merge join; - Adaptive Query Execution: включён по умолчанию с Spark 3.2. По реальной статистике после shuffle объединяет мелкие партиции, меняет sort-merge на broadcast и дробит перекошенные партиции;
- dynamic partition pruning: при джоине с отфильтрованным измерением отсекает партиции большой таблицы фактов;
- конвейер узких трансформаций:
selectиfilterвнутри стадии идут без записи на диск, граница стадии проходит только по shuffle.
Отдельно оговорите, что кэш (cache(), persist()) Spark сам не ставит, это ваше решение.
Где спотыкаются
Пишут логику на Python UDF. Для Catalyst это чёрный ящик: фильтр через него не проталкивается, а данные гоняются между JVM и Python. Встроенные функции из pyspark.sql.functions почти всегда быстрее.
Кэшируют всё подряд. Кэш занимает память executors и окупается только при повторном использовании.
Путают repartition и coalesce: первый делает полный shuffle, второй только сливает партиции и может оставить перекос.