Простое объяснение двух способов изменить число частей данных в Spark, их цены и ограничений без программного кода.
Почему один набор разбит на части
Большой набор данных редко обрабатывает один компьютер целиком. Spark делит его на части, которые могут выполняться параллельно на разных рабочих узлах. Представьте стопку накладных, разложенную по нескольким столам. Если столов мало, люди ждут своей очереди; если слишком много мелких стопок, время уходит на организацию работы. Число частей влияет на то, как распределяется обработка, но само по себе не говорит, насколько быстро завершится задача.
В PySpark встречаются два названия для изменения числа частей: repartition и coalesce. Это названия операций, а не два разных формата хранения. Вопрос читателя здесь простой: когда данные стоит распределить заново, а когда достаточно объединить уже существующие части?
Перераспределение: открыть новую раскладку
Repartition создаёт новую раскладку частей. Это позволяет как увеличить, так и уменьшить их количество и перераспределить строки между рабочими узлами. Такая гибкость имеет цену: данные приходится перемещать, а сеть и вычисления тратят на это время. Документация Apache Spark описывает перераспределение как новую разметку набора по заданному числу частей.
Вернёмся к накладным. Если на одном столе скопилось большинство документов, простое объединение соседних стопок не поможет остальным сотрудникам. При новой раскладке документы разносят по столам заново. Это полезно при сильном перекосе, но само перекладывание тоже занимает время. Поэтому перераспределение имеет смысл оценивать вместе с последующей задачей, а не считать бесплатным ускорением.
Укрупнение: объединить без полной перестановки
Coalesce обычно применяют, когда частей стало слишком много и их нужно укрупнить. По описанию Apache Spark, существующие части группируются без полного обмена данными между узлами. Это часто экономит перемещение. Но такая операция не создаёт больше частей, чем уже есть, и не обязана исправлять неравномерную раскладку.
Например, после отбора из большого массива в каждой части осталось немного записей. Несколько небольших частей можно объединить перед дальнейшей работой. Если же почти все записи по-прежнему сосредоточены в одной части, простое укрупнение сохранит перекос. Выбор зависит не только от количества частей, но и от того, сколько данных находится в каждой.
Почему один огромный кусок бывает плохой идеей
Условно представим, что десять сотрудников могут одновременно проверять десять стопок документов. Если всё сложить в одну, девять человек останутся без работы. Похожая проблема возникает, когда число частей резко сокращают до одной: Apache Spark предупреждает, что вычисление может использовать меньше рабочих узлов, чем хотелось бы. Одна часть иногда нужна для небольшого результата, но превращать её в правило для всех наборов нельзя.
Обратная крайность — менять число частей после каждого действия «на всякий случай». Новая раскладка добавляет работу, а укрупнение может снизить параллельность. Лучше сначала понять, где именно возникла задержка: в чтении, в неравномерном распределении, в обмене данными или при сохранении результата. Без этого настройка легко маскирует причину.
Как выбрать направление проверки
Если частей слишком мало для имеющейся работы или они сильно различаются по объёму, исследуют перераспределение. Если после отбора появилось множество почти пустых частей, рассматривают укрупнение. Затем сравнивают время всей задачи и загрузку узлов на одинаковом наборе, а не только число частей в отчёте. Эти наблюдения помогают принять решение без универсальной «правильной» цифры.
О движении данных между узлами подробнее рассказывает статья про shuffle в Spark, а о последствиях слишком мелкой записи — материал о маленьких файлах. Если хотите изучить обработку данных системно, посмотрите курс PySpark для инженеров и аналитиков данных и сопоставьте программу со своими задачами.


