为什么SparkContext.parallelize使用驱动程序的内存?

时间:2017-09-17 08:46:29

标签: apache-spark pyspark

现在我必须在pyspark( Spark 2.1.0 )中使用 sc.parallelize()创建并行化集合。

我的驱动程序中的集合很大。当我并行化它时,我发现它在主节点中占用了大量内存。

在将节点并行化到每个工作节点之后,主节点的 spark 中的集合仍然保持。 这是我的代码示例:

# my python code
sc = SparkContext()
a = [1.0] * 1000000000
rdd_a = sc.parallelize(a, 1000000)
sum = rdd_a.reduce(lambda x, y: x+y)

我已经尝试了

del a

摧毁它,但它没有起作用。 java进程的火花仍在使用大量内存。

创建 rdd_a 后,如何销毁 a 以释放主节点' s存储器?

谢谢!

3 个答案:

答案 0 :(得分:2)

主人的工作是协调工人,并在工人完成当前任务后给工人一个新任务。为此,主人需要跟踪为给定计算需要完成的所有任务。

现在,如果输入是文件,则任务看起来就像“从X到Y读取文件F”。但是因为输入在内存中开始,所以任务看起来像1000个数字。鉴于主人需要跟踪所有1,000,000个任务,这个任务变得非常大。

答案 1 :(得分:1)

  

我的驱动程序中的集合很大。当我并行化它时,我发现它在主节点中占用了大量内存。

它应该如何以及为什么SparkContext.parallelize仅用于演示和学习目的,即用于非常小的数据集。

引用parallelize

的标量
  

parallelize [T](seq:Seq [T],numSlices:Int = defaultParallelism):RDD [T] 分发本地Scala集合以形成RDD。

注意"本地Scala集合"这意味着您要映射到RDD(或从中创建RDD)的集合已经存在于驱动程序的内存中。

在您的情况下,a是一个本地Python变量,Spark对此一无所知。使用parallelize时会发生的情况是局部变量(已经存在于内存中)被包含在这个名为RDD的良好数据抽象中。它只是包含驱动程序内存中数据的包装器。 Spark无法做很多事情。太晚了。但是Spark很好地发挥作用并假装数据与您可以使用Spark处理的其他数据集一样分布。

这就是为什么parallelize仅适用于小数据集(主要用于演示)的原因。

答案 2 :(得分:-1)

您应该减少并行数。通常过多的并行性会产生反作用,因为开始和完成每个任务可能比任务本身花费更多的时间