Какое должно быть оптимальное значение для spark.sql.shuffle.partitions или как мы увеличиваем разделы при использовании Spark SQL?

Привет, я использую Spark SQL фактически hiveContext.sql(), который использует группу по запросам, и я сталкиваюсь с проблемами OOM. Поэтому думаем об увеличении значения spark.sql.shuffle.partitions от 200 по умолчанию до 1000, но это не помогает. Пожалуйста, исправьте меня, если я ошибаюсь, эти разделы будут обмениваться данными shuffle load, поэтому больше разделов меньше данных для хранения. Пожалуйста, объясните, что я новичок в Spark. Я использую Spark 1.4.0, и у меня есть около 1 ТБ несжатых данных для обработки с помощью hiveContext.sql() по запросам.

Ответ 1

Если у вас заканчивается память в случайном порядке, попробуйте установить spark.sql.shuffle.partitions на 2001.

Spark использует другую структуру данных для хранения в случайном порядке, когда количество разделов больше 2000:

private[spark] object MapStatus {

  def apply(loc: BlockManagerId, uncompressedSizes: Array[Long]): MapStatus = {
    if (uncompressedSizes.length > 2000) {
      HighlyCompressedMapStatus(loc, uncompressedSizes)
    } else {
      new CompressedMapStatus(loc, uncompressedSizes)
    }
  }
...

Мне очень жаль, что они не позволят вам настроить это самостоятельно.

Кстати, я нашел эту информацию в слайдовой колоде Cloudera.

Ответ 2

ОК, поэтому я думаю, что ваша проблема более общая. Он не специфичен для Spark SQL, это общая проблема с Spark, где он игнорирует количество разделов, которые вы указываете, когда файлов мало. Кажется, что у Spark столько же разделов, сколько количество файлов на HDFS, если вы не вызываете repartition. Поэтому вызов repartition должен работать, но есть предостережение в том, что вы производите ненужное перемещение.

Я поднял этот вопрос некоторое время назад и еще не получил хорошего ответа: (

Искра: увеличивайте количество разделов, не вызывая тасование?

Ответ 3

Фактически это зависит от ваших данных и вашего запроса, если Spark должен загрузить 1Tb, что-то не так в вашем дизайне.

Используйте веб-интерфейс супербэка для просмотра DAG, означайте, как Spark переводит ваш SQL-запрос на задания/этапы и задачи.

Полезными метриками являются "Input" и "Shuffle".

  • Разделите свои данные (макет Hive/directory like/year = X/month = X)
  • Используйте функцию spark CLUSTER BY, чтобы работать на каждый раздел данных
  • Используйте формат файла ORC/Parquet, поскольку они предоставляют "Push-down filter", бесполезные данные не загружаются в Spark
  • Проанализируйте историю искры, чтобы увидеть, как Spark считывает данные.

Кроме того, OOM может произойти на вашем драйвере?

- > Это еще одна проблема, драйвер будет собирать в конце нужные вам данные. Если вы запрашиваете слишком много данных, драйвер будет OOM, попробуйте ограничить ваш запрос или написать другую таблицу (синтаксис Spark CREATE TABLE ...AS).

Ответ 4

Я наткнулся на это сообщение от Cloudera о разделении Hive. Обратите внимание на раздел "Указатели", в котором говорится о количестве разделов и количестве файлов в каждом разделе, что приводит к перегрузке узла имени, что может вызвать OOM.