Spark: Разница между Shuffle Write, Shuffle spill (память), Shuffle spill (диск)?

У меня есть следующая искра, пытаясь сохранить все в памяти:

val myOutRDD = myInRDD.flatMap { fp =>
  val tuple2List: ListBuffer[(String, myClass)] = ListBuffer()
        :

  tuple2List
}.persist(StorageLevel.MEMORY_ONLY).reduceByKey { (p1, p2) =>
   myMergeFunction(p1,p2)
}.persist(StorageLevel.MEMORY_ONLY)

Однако, когда я посмотрел на работу трекера, у меня все еще есть много Shuffle Write и Shuffle разлива на диск...

Total task time across all tasks: 49.1 h
Input Size / Records: 21.6 GB / 102123058
Shuffle write: 532.9 GB / 182440290
Shuffle spill (memory): 370.7 GB
Shuffle spill (disk): 15.4 GB

Тогда работа завершилась неудачно, потому что "no space left on device"... Мне интересно, как 532,9 ГБ Shuffle пишут здесь, записывается ли она на диск или в память?

Кроме того, почему на диске все еще выпадает 15,4 Г данных, в то время как я специально прошу сохранить их в памяти?

Спасибо!

Ответ 1

Вызов persist в вашем коде полностью теряется, если вы не получаете доступ к RDD несколько раз. Какой смысл хранить что-то, если вы никогда не обращаетесь к нему? Кэширование не влияет на поведение в случайном порядке, кроме того, что вы можете избежать повторного воспроизведения в случайном порядке, сохраняя кеширование вывода.

Переполнение в случайном порядке контролируется параметрами конфигурации spark.shuffle.spill и spark.shuffle.memoryFraction. Если параметр spill включен (по умолчанию), то файлы перетасовки будут выгружаться на диск, если они начнут использовать больше, чем задано memoryFraction (по умолчанию 20%).

Метрики очень запутанны. Мое чтение code заключается в том, что "Shuffle spill (memory)" - это объем памяти, который был освобожден, поскольку на диск было пропущено. code для "Shuffle spill (disk)" выглядит как сумма, фактически записанная на диск. С помощью code для "Shuffle write" я думаю, что это сумма, записанная на диск напрямую, а не как разлив из сортировщика.

Ответ 2

Разброс в случайном порядке (память) - это размер десериализованной формы данных в памяти в то время, когда мы проливаем его, тогда как переполнения (диска) является размер сериализованной формы данных на диске после того, как мы его прольем. Вот почему последний, как правило, намного меньше первого. Обратите внимание, что обе метрики агрегируются в течение всей задачи (т.е. Внутри каждой задачи вы можете разливать несколько раз).

Ответ 3

перетасовать данные

Запись в случайном порядке означает, что данные, которые были записаны в вашу локальную файловую систему во временном кэше. В режиме кластеров пряжи вы можете установить это свойство с атрибутом "yarn.nodemanager.local-dirs" в файле yarn-site.xml. Поэтому "запись в случайном порядке" означает размер данных, которые вы написали во временное место; "Shuffle spill", скорее, ваш результат в случайном порядке. Во всяком случае, эти цифры накапливаются.

Ответ 4

Еще одно замечание о том, как предотвратить разлив в случайном порядке, так как я думаю, что это самая важная часть вопроса из аспекта производительности (запись в случайном порядке, как упоминалось выше, является необходимой частью перетасовки).

Проливание происходит, когда чтение в случайном порядке, любой редуктор не может вместить все записи, назначенные ему в памяти в пространстве тасования на этом исполнителе. Если ваш случайный выбор несимметричен (например, некоторые разделы вывода намного больше, чем некоторые входные разделы), вы можете переливаться в случайном порядке, даже если разделы "помещаются в память" перед перемещением. Лучший способ контролировать это A) балансировка перетасовки... например, изменение кода для уменьшения перед перетасовкой или путем перетасовки на разных клавишах  или B) изменение настроек памяти в случайном порядке, как указано выше Учитывая степень разлива на диск, вам, вероятно, нужно сделать A, а не B.