现在我必须在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存储器?
谢谢!
答案 0 :(得分:2)
主人的工作是协调工人,并在工人完成当前任务后给工人一个新任务。为此,主人需要跟踪为给定计算需要完成的所有任务。
现在,如果输入是文件,则任务看起来就像“从X到Y读取文件F”。但是因为输入在内存中开始,所以任务看起来像1000个数字。鉴于主人需要跟踪所有1,000,000个任务,这个任务变得非常大。
答案 1 :(得分:1)
我的驱动程序中的集合很大。当我并行化它时,我发现它在主节点中占用了大量内存。
它应该如何以及为什么SparkContext.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)
您应该减少并行数。通常过多的并行性会产生反作用,因为开始和完成每个任务可能比任务本身花费更多的时间