Apache Spark: установка экземпляров исполнителей не изменяет исполнителей
У меня есть приложение Apache Spark, работающее на кластере YARN (искра имеет 3 узла в этом кластере) в режиме кластера.
Когда приложение запускается, Spark-UI показывает, что на третьем node работают 2 исполнителя (каждый из которых работает с другим node) и драйвер.
Я хочу, чтобы приложение использовало больше исполнителей, поэтому я попытался добавить аргумент --num-executors в Spark-submit и установить его в 6.
spark-submit --driver-memory 3G --num-executors 6 --class main.Application --executor-memory 11G --master yarn-cluster myJar.jar <arg1> <arg2> <arg3> ...
Однако число исполнителей остается равным 2.
В искровом UI я вижу, что параметр spark.executor.instances равен 6, как я и предполагал, и как-то все еще есть только 2 исполнителя.
Я даже попытался установить этот параметр из кода
sparkConf.set("spark.executor.instances", "6")
Опять же, я вижу, что параметр был установлен в 6, но все еще есть только 2 исполнителя.
Кто-нибудь знает, почему я не мог увеличить количество моих исполнителей?
yarn.nodemanager.resource.memory-mb - 12 г в файле пряжи .xml
Ответы
Ответ 1
Увеличить yarn.nodemanager.resource.memory-mb
в yarn-site.xml
С 12g за node вы можете запускать только драйвер (3g) и 2 исполнителя (11g).
Node1 - драйвер 3g (+ 7% накладных расходов)
Node2 - исполнитель1 11g (+ 7% служебных данных)
Node3 - executor2 11g (+ 7% служебных данных)
теперь вы запрашиваете у исполнителя3 из 11g, а node имеет доступную 11-граммовую память.
для 7% накладных расходов ссылаются на spark.yarn.executor.memoryOverhead и spark.yarn.driver.memoryOverhead в https://spark.apache.org/docs/1.2.0/running-on-yarn.html
Ответ 2
Обратите внимание, что yarn.nodemanager.resource.memory-mb
- это общая память, которую один NodeManager может выделить во всех контейнерах на одном узле.
В вашем случае, поскольку yarn.nodemanager.resource.memory-mb = 12G
, если вы добавляете память, выделенную для всех контейнеров YARN на каком-либо отдельном узле, она не может превышать 12G.
Вы запросили 11G (-executor-memory 11G
) для каждого контейнера Spark Executor. Хотя 11G меньше 12G, это все равно не сработает. Зачем?
- Потому что вы должны учитывать
spark.yarn.executor.memoryOverhead
, который является min(executorMemory * 0.10, 384)
(по умолчанию, если вы не переопределите его).
Итак, следующая математика должна выполняться:
spark.executor.memory
+ spark.yarn.executor.memoryOverhead
<= yarn.nodemanager.resource.memory-mb
См. Https://spark.apache.org/docs/latest/running-on-yarn.html для получения последней документации по spark.yarn.executor.memoryOverhead
Более того, spark.executor.instances
- это просто запрос. Spark ApplicationMaster для вашего приложения отправит в YARN ResourceManager запрос на количество контейнеров = spark.executor.instances
. Запрос будет удовлетворен ResourceManager на узле NodeManager на основании:
- Доступность ресурса на узле. Планирование YARN имеет свои нюансы - это хороший пример того, как работает YARN FairScheduler.
- Был ли
yarn.nodemanager.resource.memory-mb
превышен на узле: - (количество искровых контейнеров, работающих на узле * (
spark.executor.memory
+ spark.yarn.executor.memoryOverhead
)) <= yarn.nodemanager.resource.memory-mb
*
Если запрос не будет удовлетворен, запрос будет поставлен в очередь и будет удовлетворен при выполнении вышеуказанных условий.
Ответ 3
Чтобы использовать --executor-cores
кластер на полную мощность, вам необходимо установить значения для --num-executors
, --executor-cores
и --executor-memory
в соответствии с вашим кластером:
-
--num-executors
флаг командной строки --num-executors
или spark.executor.instances
конфигурации spark.executor.instances
управляет количеством запрошенных исполнителей; -
--executor-cores
командной строки --executor-cores
или spark.executor.cores
конфигурации spark.executor.cores
управляет количеством одновременных задач, которые может выполнить исполнитель; -
--executor-memory
командной строки --executor-memory
или spark.executor.memory
конфигурации spark.executor.memory
управляют размером кучи.
Ответ 4
У вас есть только 3 узла в кластере, и один будет использоваться в качестве драйвера, у вас осталось всего 2 узла, как вы можете создать 6 исполнителей?
Я думаю, вы смутили --num-executors
с помощью --executor-cores
.
Чтобы увеличить concurrency, вам нужно больше ядер, вы хотите использовать все процессоры в своем кластере.