Одна задача Spark идёт 40 минут, остальные завершились за две
Ежедневный джоб соединяет факты с профилями клиентов по client_id. В Spark UI: 199 задач стадии завершились за 2 минуты, одна выполняется 40 минут и в итоге падает с OutOfMemory на исполнителе.
При разборе выяснилось: в фактах 60% строк имеют client_id = -1 — это заглушка для неопознанных клиентов.
Что происходит и как это лечить?
- Не хватает памяти исполнителям: достаточно поднять spark.executor.memory и долю памяти под перемешивание, тогда тяжёлая задача доедет до конца и стадия закроется.
- Классический перекос по ключу: все строки с -1 попадают в один раздел и достаются одному исполнителю. Лечится отдельной обработкой горячего ключа или подмешиванием соли в ключ соединения.
- Мало разделов: repartition(2000) перед соединением распределит данные равномернее и разобьёт проблемную задачу на несколько мелких.
- Файлы источника слишком крупные: нужно перечитать вход мелкими файлами или уменьшить максимальный размер раздела при чтении, чтобы задачи получились одинаковыми.
