Какие преимущества у Spark по сравнению с Pandas
Что проверяют
Понимаете ли вы, при каком объёме и характере данных Spark вообще нужен, и знаете ли его цену. Следом обычно спрашивают, когда вы бы взяли Pandas, Polars или DuckDB, и что такое shuffle.
Как отвечать
Сначала граница применимости: Pandas работает на одной машине и держит данные в памяти, причём промежуточные копии легко съедают в несколько раз больше объёма исходного файла. Spark распределяет данные по партициям между исполнителями кластера.
Дальше преимущества Spark:
- горизонтальное масштабирование: объём ограничен кластером, а не оперативной памятью ноутбука;
- ленивые вычисления и оптимизатор: трансформации только строят план, Catalyst переставляет фильтры, выбрасывает лишние колонки и проталкивает условия в источник (predicate pushdown), а с Parquet читает только нужные партиции и колонки. Исполняется всё по действию:
count(),write,collect(); - отказоустойчивость: упавшую задачу пересчитывают по lineage на другом узле;
- экосистема: чтение из HDFS, S3, Hive, Delta и Iceberg, Spark SQL, MLlib, потоковая обработка через Structured Streaming;
- единый API: тот же код на DataFrame идёт и на гигабайте, и на терабайтах, есть и
pyspark.pandasс синтаксисом, похожим на Pandas.
Честно назовите минусы: запуск JVM и планирование задач дают накладные расходы в секунды, shuffle при groupBy и join гоняет данные по сети, Python UDF медленные из-за сериализации между JVM и Python. Поэтому на данных, которые помещаются в память одной машины, Pandas, Polars или DuckDB обычно быстрее и проще.
Где спотыкаются
Говорят, что Spark всегда быстрее. На паре гигабайт он проиграет локальному инструменту и по времени, и по сложности отладки.
Вызывают toPandas() или collect() на большом датафрейме. Все данные едут на драйвер, и он падает по памяти.
Не понимают ленивость: удивляются, что два действия подряд пересчитывают весь план заново, хотя промежуточный результат стоило закешировать через cache(). Сюда же построчные Python UDF там, где хватило бы встроенных функций из pyspark.sql.functions или векторизованной pandas UDF.