Найти и обезвредить Spill в Spark-приложениях: причины и решения

обучение Spark, курсы Apache Spark Для разработчиков примеры обучение, spill in spark apps, проблемы с производительностью Spark-приложений, обучение большим данным, курсы Big Data для разработчиков, Школа Больших Данных Учебный Центр Коммерсант

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

Что такое spill и почему он случается: под капотом Spark-приложений

При том, что spill можно рассматривать как встроенный в Apache Spark способ устранения ошибки нехватки памяти (OutOfMemory, OOM), он сам может стать причиной снижения производительности приложения. Каждой задаче назначается раздел памяти для обработки данных. Если данных слишком много, и они не помещаются в выделенный для задачи раздел памяти, чтобы не потерять вычисления, данные записываются (переливаются) на диск.

Таким образом, переброс или spill – это термин для обозначения процесса перемещения RDD из RAM на диск, а затем снова обратно в RAM. Это происходит, когда RDD слишком большой для размещения в памяти и фреймворк вынужден выполнять дорогостоящие операции чтения и записи на диск, чтобы освободить локальную оперативную память и избежать OOM-ошибки, которая может привести к сбою приложения. Такая ситуация случается по одной из следующих причин:

  • значение параметра spark.sql.files.maxPartitionBytes – количество байтов для упаковки в один раздел при чтении файлов формата Parquet, JSON и ORC. По умолчанию это свойство задано 128 МБ. Если установить раздел, считываемый Spark намного больше, например, 1 ГБ, активное поглощение может не вызвать утечку памяти, но вызовет spill-эффект.
  • операция explode() на небольшом массиве данных с соединениями и декартовыми соединениями (CrossJoin) двух таблиц, результат которого может превысить размер раздела;
  • агрегации по искаженным данным, которые неравномерно распределены по узлам кластера, также потенциально могут создать очень большой раздел и вызвать перенос данных из памяти на диск и обратно. Подробнее о том, как возникают перекосы и как с ними бороться, читайте в нашей новой статье.

Разобрав, что такое spill-эффект и чем он плох, далее рассмотрим, как его обнаружить.

Как обнаружить переброс данных из памяти на диск: 4 способа в UI

Spill представлен двумя значениями, которые всегда соседствуют друг с другом:

  • Memory – размер данных в том виде, в каком они существуют в памяти до того, как они будут переписаны;
  • Disk – размер данных, которые перебрасываются на диск, сериализуются, записываются на диск и сжимаются.

С точки зрения данных оба хранят одни и те же данные, но на диске это значение обычно меньше, т.к. данные здесь сжимаются более эффективно, чем в памяти. Отследить переброс данных из памяти на диск можно прямо в пользовательском интерфейсе на странице сведений о конкретном этапе в Spark UI:

  • в общих метриках;
  • в метриках, агрегированных по исполнителям;
  • в таблице задач;
  • в плане выполнения SQL-запроса и его деталях.
Spark UI, Spark spill, Обучение разработчиков Spark приложений примеры
Как идентифицировать spill в Spark UI

Как устранить проблему перезаписи данных в Spark-приложениях из памяти на диск и обратно

Прежде всего отметим, что не существует универсального решения проблемы spill-эффекта, т.к. она зависит от множества причин. Причем не каждый вариант решения можно реализовать на практике. Самый простой и дорогостоящий способ — выделить кластер с большим объемом памяти на одного worker’а. Однако, это может не сработать, если нет возможности менять конфигурацию Spark-кластера. Поэтому лучше сперва устранить главную причину, например, если spill вызван перекосом данных, когда они неравномерно распределены по узлам кластера, при устранении этого фактора spill также автоматически прекратится.

Также можно поработать с разделами следующими способами:

  • уменьшить размер каждого раздела, увеличив их количество;
  • задать значение параметра sql.files.maxPartitionBytes;
  • явно перераспределить данные с помощью методов repartition() или coalesce(), о которых мы писали здесь, чтобы устранить перекос и сделать их распределение по кластеру более равномерным. Также можно попробовать криптографический метод модификации хэш-функции, о чем мы рассказываем в новой статье.
  • изменить значение параметра spark.sql.shuffle.partitions — количество разделов для использования при перетасовке данных для объединений или агрегатов, по умолчанию равен 200.

Читайте в нашей новой статье, как фильтр Блума помогает снизить число обращений к жесткому диску и где это пригодится при работе Apache Spark с Parquet-файлами. А про spill-файлы в MPP-СУБД Greenplum мы рассказываем здесь.

Больше подробностей эксплуатации Apache Spark для разработки распределенных приложений и аналитики больших данных вам помогут узнать специализированные курсы в нашем лицензированном учебном центре обучения и повышения квалификации для разработчиков, менеджеров, архитекторов, инженеров, администраторов, Data Scientist’ов и аналитиков Big Data в Москве:

Я даю свое согласие на обработку персональных данных и соглашаюсь с политикой конфиденциальности.

Источники

  1. https://medium.com/curious-data-catalog/spill-often-ignored-sparks-performance-problem-9b4c1ea962f
  2. https://xuechendi.github.io/2019/04/15/Spark-Shuffle-and-Spill-Explained
  3. https://medium.com/road-to-data-engineering/spark-performance-optimization-series-2-spill-685126e9d21f
  4. https://spark.apache.org/docs/latest/sql-performance-tuning.html
Поиск по сайту