Spark Python 性能调优

Spark Python Performance Tuning

我使用以下命令为 Spark 开发创建了一个 iPython notebook:

ipython notebook --profile=pyspark

然后我使用 Python 代码创建了一个 sc SparkContext,如下所示:

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,在文档

Amount of memory to use per executor process, in the same format as JVM memory strings

这是否意味着在一个节点上运行的所有进程的累积内存不会超过该上限?如果是这样,我应该将该数字设置为尽可能高的数字吗?

这也是一些属性的列表,是否有一些其他参数我可以从默认值调整以提高性能。

谢谢!

Does that mean the accumulated memory of all the processes running on one node will not exceed that cap?

是的,如果你在 YARN-client 模式下使用 Spark,否则它只限制 JVM。

然而,YARN 的这个设置有一个棘手的问题。 YARN 将累积内存限制为 spark.executor.memory 并且 Spark 对执行程序 JVM 使用相同的限制,在这样的限制中没有 Python 的内存,这就是为什么我不得不关闭 YARN 限制。

关于根据您的独立 Spark 配置对您的问题的诚实回答: 不,spark.executor.memory 不限制 Python 的内存分配。

顺便说一句,将选项设置为 SparkConf 不会对 Spark 独立执行程序产生任何影响,因为它们已经启动。阅读更多关于 conf/spark-defaults.conf

If that is the case, should I set that number to a number that as high as possible?

您应该将其设置为平衡数。 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 将被 Spark 缓存使用,0.4 * spark.executor.memory - 执行器 JVM,0.5 * spark.executor.memory - Python.

您可能还想调整 spark.storage.memoryFraction,默认情况下为 0.6

Does that mean the accumulated memory of all the processes running on one node will not exceed that cap? If that is the case, should I set that number to a number that as high as possible?

没有。通常您在一个节点上有多个执行程序。所以 spark.executor.memory 指定 one executor 可以占用多少内存。

如果您希望从 Spark 返回大量数据,您还应该检查 spark.driver.memory 并对其进行调整。

是的,它也部分覆盖了 Python 内存。在 JVM 中被解释为 Py4J 代码和 运行 的部分。

Spark uses Py4J internally 将您的代码翻译成 Java 并 运行 就这样。例如,如果您将 Spark 管道作为 RDD 上的 lambda 函数,那么 Python 代码实际上将通过 Py4J 在执行程序上 运行。另一方面,如果你 运行 一个 rdd.collect() 然后用它作为本地 Python 变量做一些事情,那将 运行 通过 Py4J 在你的驱动程序上。