为什么从Spark数据帧联接中收集到OutOfMemory错误会通过增量评估得到解决?

时间:2018-07-09 19:57:40

标签: python apache-spark

我正在学习Spark,并试图进一步了解Spark如何使用和管理内存。我正在以local[*]主机配置在本地模式下运行Spark应用程序。

简而言之,我有很多非常小的数据框(2000行x 5列),其中有一个uid列,我试图加入一个更大的数据框(2000行x 150列),也有一个{ {1}}列。我的联接代码:

uid

当我最终调用 df=df.join( self.sqlContext.createDataFrame(join1,schema=['uid', 'join1']),on='uid') print(f"Joined join1") df=df.join( self.sqlContext.createDataFrame(join2,schema=['uid', 'join2']), on='uid') print(f"Joined join2") df=df.join( self.sqlContext.createDataFrame(join3,schema=['uid', 'join3']), on='uid') print(f"Joined join3") df=df.join( self.sqlContext.createDataFrame(join4,schema=['uid', 'join4']), on='uid') print(f"Joined join4") 作为强制评估的动作时,我发现Spark成功将数据连接在一起,但是随后在收集阶段遇到了内存错误:

df.take(100)

为纠正这种情况,我每加入几个java.lang.OutOfMemoryError: Unable to acquire 100 bytes of memory, got 0 就可以强制评估:

df.count()

我可能需要进行40个联接,每10个联接,我将强制使用 df=df.join( self.sqlContext.createDataFrame(join1,schema=['uid', 'join1']),on='uid') print(f"Joined join1") df=df.join( self.sqlContext.createDataFrame(join2,schema=['uid', 'join2']), on='uid') print(f"Joined join2") df=df.join( self.sqlContext.createDataFrame(join3,schema=['uid', 'join3']), on='uid') print(f"Joined join3") print(df.count()) # force evaluation print(df.cache()) # cache new dataframe df=df.join( self.sqlContext.createDataFrame(join4,schema=['uid', 'join4']), on='uid') print(f"Joined join4") 进行评估。当我尝试这种方法时,我可以执行我最后的df.count()操作。

我的问题是-为什么这样做?如果我们直到最后一个{{1 }}。但是,如果我们在执行连接时逐步评估和缓存,则collect()会起作用。在SparkUI中,我看到有许多collect()正在发生,但是我不太了解执行准确的早期评估如何减少最终collect()期间驱动程序的内存负载。

0 个答案:

没有答案