2015-01-03 3 views
5

Я воспитывался ноутбук IPython для развития Спарк, используя следующую команду:Спарк Python Performance Tuning

ipython notebook --profile=pyspark 

И я создал sc SparkContext используя код Python вроде этого:

import sys 
import os 
os.environ["YARN_CONF_DIR"] = "/etc/hadoop/conf" 
sys.path.append("/opt/cloudera/parcels/CDH/lib/spark/python") 
sys.path.append("/opt/cloudera/parcels/CDH/lib/spark/python/lib/py4j-0.8.1-src.zip") 
from pyspark import SparkContext, SparkConf 
from pyspark.sql import * 

sconf = SparkConf() 
conf = (SparkConf().setMaster("spark://701.datafireball.com:7077") 
    .setAppName("sparkapp1") 
    .set("spark.executor.memory", "6g")) 
sc = SparkContext(conf=conf) 
sqlContext = SQLContext(sc) 

Я хочу чтобы лучше понять spark.executor.memory, в документе

Количество памяти для использования на каждом исполнительном процессе, в том же формате, что и строки памяти JVM

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

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

Спасибо!

ответ

5

Означает ли это, что накопленная память всех процессов, работающих на , не может превышать этот узел?

Да, если вы используете Spark в режиме YARN-client, в противном случае он ограничивает только JVM.

Однако, с этой целью сложно установить этот параметр с помощью YARN. YARN ограничивает накопленную память до spark.executor.memory, а Spark использует тот же предел для JVM-исполнителя, для Python в таких пределах нет памяти, поэтому мне пришлось отключить ограничения YARN.

Что касается честного ответа на ваш вопрос в соответствии с вашей автономной конфигурацией Spark: Нет, spark.executor.memory не ограничивает выделение памяти Python.

BTW, установка опции SparkConf не влияет на автономных исполнителей Spark, поскольку они уже установлены. Узнайте больше о conf/spark-defaults.conf

Если это так, следует ли установить это число на число, максимально возможное?

Вы должны установить его на сбалансированное число. Существует определенная особенность JVM: она в конечном итоге выделит spark.executor.memory и никогда не будет ее освобождать. Вы не можете установить spark.executor.memory в TOTAL_RAM/EXECUTORS_COUNT, так как он займет всю память для Java.

В моей среде, я использую spark.executor.memory=(TOTAL_RAM/EXECUTORS_COUNT)/1.5, что означает, что 0.6 * spark.executor.memory будет использоваться кэш Спарк, 0.4 * spark.executor.memory - исполнитель JVM и 0.5 * spark.executor.memory - на Python.

Возможно, вы также захотите настроить spark.storage.memoryFraction, то есть 0.6 по умолчанию.

+0

Просьба уточнить ваш второй-последний абзац. Как вы пришли к вычислениям 0.6, 0.4 и особенно 0.5, взятым python – javadba

+0

@javadba, 0.6 is spark.storage.memoryFraction (по умолчанию, https://spark.apache.org/docs/1.3.0/configuration.html) , 0.4 - (1 - 0.6), а 0.5 для Python - мое ожидание для моего использования (в худшем случае вы можете ожидать использования памяти 0.6 * 2 для Python или даже больше, поэтому 0.5 - это чисто эмпирическое значение для моей среды) , –

+0

Давайте рассмотрим использование numpy и некоторых библиотек обучения компьютера python, которые используют собственный код. Вся эта память исходит от spark.executor.memory - или просто от O/S OUTSIDE от искры? Благодаря! – javadba

0

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

Nope. Обычно у вас есть несколько исполнителей на узле. Поэтому spark.executor.memory указывает, сколько памяти один исполнитель может взять.

Вы также должны проверить spark.driver.memory и настроить его, если вы ожидаете, что из Spark будет возвращен значительный объем данных.

И да, это частично покрывает память Python. Часть, которая интерпретируется как код Py4J и запускается в JVM.

Spark uses Py4J internally для перевода вашего кода на Java и запускает его как таковой. Например, если у вас есть конвейер Spark как лямбда-функции на RDD, тогда этот код Python будет выполняться на исполнителях через Py4J. С другой стороны, если вы запустите rdd.collect(), а затем сделайте что-то с этим в качестве локальной переменной Python, которая будет работать через Py4J на вашем драйвере.