簡體   English   中英

Pyspark 迭代列加法 memory 泄漏

[英]Pyspark iterative column addition memory leak

我一直在嘗試對 pyspark 數據幀執行一些迭代計算。 列基於先前的列添加到 df。 但是我注意到使用的 memory 不斷增加。 一個簡單的例子如下所示。

from pyspark import SparkContext, SparkConf
from pyspark.sql import SQLContext
from pyspark import Row

conf = SparkConf().setAppName("myFirstApp").setMaster("local")
sc = SparkContext(conf=conf)
sqlContext = SQLContext(sc)

df = [Row(Z_0=0.0, Z_1=0.0)]
df = sc.parallelize(df).toDF()
for each in range(0,400):
    df = df.withColumn("Z_"+str(each+2), df['Z_'+str(each+1)]+1)

我的理解是,我實際上是在構建一個執行計划,而不一定是數據本身。 但是,使用collect(), count(), show()或轉換為 rdd 甚至刪除 df 調用 df 的執行都無法釋放 memory。 我已經看到 1.2GB 的 memory 用於上述任務。 似乎垃圾收集無法清理以前的中間df對象,或者這些對象可能永遠不會被取消引用。

有沒有更好的方法來構建這種類型的迭代計算,或者有沒有辦法清理這些中間 df? 請注意,此處出現的簡單+1只是更復雜計算的最小示例模擬。

我一直在處理同樣的事情,並沒有想出一個好的解決方案。

作為臨時解決方案:將應用程序拆分為多個.py 文件並逐個執行它們,這將導致垃圾收集釋放所有不必要的緩存。

我發現您可以調用take()來刪除執行計划,只留下值。 請參閱相關調用的最后一行。

from pyspark import SparkContext, SparkConf
from pyspark.sql import SQLContext
from pyspark import Row

conf = SparkConf().setAppName("myFirstApp").setMaster("local")
sc = SparkContext(conf=conf)
sqlContext = SQLContext(sc)

df = [Row(Z_0=0.0, Z_1=0.0)]
df = sc.parallelize(df).toDF()
for each in range(0,1400):
    df = df.withColumn("Z_"+str(each+2), df['Z_'+str(each+1)]+1)
    df = sc.parallelize(df.take(df.count())).toDF()

我在關於垃圾收集是問題的問題中的陳述並不完全正確。 heap size和已used heap之間存在差異。 在使用 visualVM 進行調查時,很容易看到垃圾收集正在發生,這減少了used heap
在此處輸入圖像描述 我們看到 jvm 在處理問題中發布的代碼時遇到的問題。 到最后,我們沒有空間移動。 我們的heap size已達到最大值,此時已used heap太大,對 GC 沒有任何影響。 這種擴展不是由於數據,而是由於保留了數據沿襲信息。 我需要做的是擺脫所有這些血統,老實說,這在這個問題的上下文中並不是那么有用,只保留數據。

以下是上述答案代碼片段的簡介。 即使有 1400 列,我們保存數據也沒什么問題。 在此處輸入圖像描述

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM