如何在Spark中处理执行器内存和驱动程序内存?

53

我对在Spark中处理执行器内存和驱动程序内存感到困惑。

我的环境设置如下:

  • 128 G内存,9个VM,每个VM有16个CPU
  • Centos操作系统
  • Hadoop 2.5.0-cdh5.2.0
  • Spark 1.1.0

输入数据信息如下:

  • 从HDFS读取3.5 GB的数据文件

为了简单开发,我使用spark-submit命令,在独立集群模式下执行Python代码(8个worker、20个核心、45.3G内存)。现在我想进行性能调优,设置executor memory或driver memory。

根据Spark文档,executor memory的定义为:

每个执行器进程使用的内存量,格式与JVM内存字符串相同(例如512m,2g)。

那么驱动程序内存是怎样的呢?

3个回答

110

您需要分配给驱动程序的内存取决于作业。

如果作业基于纯转换,并且在某些分布式输出操作(如rdd.saveAsTextFile,rdd.saveToCassandra等)上终止,则驱动程序的内存需求将非常低。几百兆字节就足够了。驱动程序负责传递文件和收集度量,但不参与数据处理。

如果作业需要驱动程序参与计算,例如某些需要实现结果并在下一次迭代中广播的 ML 算法,则您的作业将依赖通过驱动程序传递的数据量。像 .collect,.taketakeSample 这样的操作将数据传递到驱动程序,因此,驱动程序需要足够的内存来分配这些数据。

例如,如果您在集群中有一个 3GB 的 rdd 并调用 val myresultArray = rdd.collect,那么您需要 3GB 的内存来保存该数据以及第一段中提到的函数所需的额外空间。


3
如果我想对20GB的数据执行 datraframe.coalesce(1).write().csv(outputDir) 操作,我需要确保分配给驱动程序的内存大于20GB吗? - Omkar Puttagunta
4
不。当您将分区数减少为1时,那个单独的分区将在一个执行器中。由于您不知道是哪一个,每个执行器都需要超过20GB。我建议您找到另一种解决方案。 - maasg

8
在Spark应用程序中,Driver负责任务调度,而Executor负责执行作业中的具体任务。如果您熟悉MapReduce,则您的map任务和reduce任务都在Executor中执行(在Spark中,它们称为ShuffleMapTasks和ResultTasks)。此外,您想要缓存的任何RDD也位于executor的JVM堆和磁盘中。因此,我认为几GB对于您的Driver来说是可以接受的。

2

Spark shell所需内存 = (Driver Memory + 384 MB)+(执行器数量 *(Executor memory + 384 MB))

这里的384 MB是Spark在执行作业时可能使用的最大内存(开销)值。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接