Как оптимизировать перетасовку в приложении Apache Spark

Я запускаю потоковое приложение Spark с двумя рабочими. Приложение имеет операции соединения и объединения.

Все пакеты завершаются успешно, но было замечено, что метрики разлива случайного воспроизведения не согласуются с размером входных или выходных данных (разлив памяти более чем в 20 раз).

Пожалуйста, найдите детали этапа искры на изображении ниже: введите описание изображения здесь

Изучив это, выяснилось, что

Перемешивание происходит, когда недостаточно памяти для перемешивания данных.

Shuffle spill (memory) - размер десериализованной формы данных в памяти на момент сброса

shuffle spill (disk) - размер сериализованной формы данных на диске после разлива

Поскольку десериализованные данные занимают больше места, чем сериализованные данные. Итак, Shuffle spill (память) больше.

Заметил, что этот размер разлитой памяти невероятно велик при больших входных данных.

Мои запросы:

Сильно ли сказывается это разливание на производительности?

Как оптимизировать это разлив памяти и диска?

Есть ли какие-либо свойства искры, которые могут уменьшить / контролировать это огромное разливание?


person Vijay Innamuri    schedule 12.06.2015    source источник
comment
@mitchus Частично Да, Я просто увеличил количество задач и выделил больше памяти для перемешивания. Кроме того, я оптимизировал свой код, чтобы сжать размер структуры данных ...   -  person Vijay Innamuri    schedule 30.07.2015


Ответы (2)


Чтобы научиться настраивать производительность Spark, требуется немало исследований и обучения. Есть несколько хороших ресурсов, включая это видео. Spark 1.4 имеет улучшенную диагностику и визуализацию в интерфейсе, которые могут вам помочь.

Таким образом, вы разливаетесь, когда размер разделов RDD в конце этапа превышает объем памяти, доступный для буфера перемешивания.

Вы можете:

  1. Вручную repartition() ваш предыдущий этап, чтобы у вас были меньшие разделы на входе.
  2. Увеличьте буфер перемешивания, увеличив память в процессах исполнителя (spark.executor.memory)
  3. Увеличьте буфер перемешивания, увеличив долю выделенной ему памяти исполнителя (spark.shuffle.memoryFraction) со значения по умолчанию 0,2. Вам нужно вернуть spark.storage.memoryFraction.
  4. Увеличьте буфер перемешивания на поток, уменьшив соотношение рабочих потоков (SPARK_WORKER_CORES) к памяти исполнителя.

Если есть опытный слушатель, мне бы хотелось узнать больше о взаимодействии настроек memoryFraction и их разумном диапазоне.

person Alister Lee    schedule 12.06.2015
comment
повторное разделение может перетасовать ненужные данные, используйте внутреннее объединение, используйте объединитель, чтобы минимизировать перетасовку. - person Venu A Positive; 08.06.2016
comment
@VenuAPositive Я думаю, он предлагал переразбить на большее количество разделов, а не на меньшее. Если бы он собирался использовать меньшее количество разделов, то объединение имело бы смысл. - person Carlos Bribiescas; 14.07.2016
comment
spark.shuffle.memoryFraction больше не используется с версии Spark 1.5, если вы не включили устаревший режим. См. spark.apache.org/docs/latest/configuration.html - person y.selivonchyk; 02.11.2017
comment
Этот ответ (хотя и полезный) на самом деле не отвечает на вопрос, почему разлив в случайном порядке намного больше, чем чтение в случайном порядке. - person abeboparebop; 12.11.2019

Чтобы добавить к приведенному выше ответу, вы также можете рассмотреть возможность увеличения количества разделов по умолчанию (spark.sql.shuffle.partitions) с 200 (когда происходит перемешивание) до числа, которое приведет к разделам размера близко к размеру блока hdfs (т.е. от 128 МБ до 256 МБ)

Если ваши данные искажены, попробуйте уловки вроде «соления ключей» для увеличения параллелизма.

Прочтите это, чтобы понять управление искровой памятью:

https://0x0fff.com/spark-memory-management/

https://www.tutorialdocs.com/article/spark-memory-management.html

person Prasad Sogalad    schedule 24.10.2019