皮斯帕克。内存不足问题。如何确保表被覆盖

2024-10-01 07:51:35 发布

您现在位置:Python中文网/ 问答频道 /正文

我目前正在尝试了解Spark计算的过程以及对内存消耗的影响。在

我在Zeppelin中使用Spark 2.3.2和Python2.7。在

基本上在下面的循环中,我要创建到集合。我用sci-kit-learn构建了一个机器学习模型,在sci-kit-learn计算之后,我对pyspark数据帧进行了大量的数据帧操作。对于每一个我都得到一个表rsmeMaeStep,它有8行10列,有小字符串或双精度值。rsmeMaeAll只是将单个分析加在一起,有8*26=208行,其中10列表示i=26。在

for i in range(26):
    df_features_train, df_features_validation = randomizer(dataFiltered)
    rsmeMaeStep, rsmeMaeAll = rsmeMaeAnalysis(rsmeMaeAll,df_features_train,df_features_test)
    print(i)

我对代码做了一些时间分析。我花了10:42的时间。循环次数为26次或更长,每次循环次数为9.6次。 下一步我有问题。下面的代码应该只是对8到206行的简单聚合。对于i=1,它需要32秒,对于i=7 4:43(长8.8倍),但对于i=26,47分钟后我有0%的时间,或者它失败,并出现内存不足的消息。在

^{pr2}$

根据逻辑,我认为每个循环中所有的表都应该被覆盖。只有小的rsmeMaeAll应该在每个循环中增加一点。但它还是一张很小的桌子。在

但Spark的行为可能有所不同。在

据我所知,第一步的sk学习代码是在第一步执行的。如果我正确理解了spark lazy求值,那么当我想打印结果时,代码中的pySpark操作就会开始执行。因此,Spark可能会将所有循环的所有表保存在内存中。对吗?在

如果我是对的,我需要代码在每个循环的末尾直接计算pySpark代码。在

我该怎么做?在

如果我这样做,会在下一个循环中触发覆盖表,还是每次循环都会增加内存消耗?我需要从内存中主动删除表吗?如何删除?在

编辑:我刚集成

rsmeMaeStep.collect()
rsmeMaeAll.collect()

以确保pyspark计算立即完成。 但是第一圈花了55秒。第七局花了10多分钟,在rsmeMaeAll.collect公司49分钟后的第8个环路。出现错误消息:

Py4JJavaError: An error occurred while calling o13488.collectToPython. :java.lang.OutOfMemoryError: Java heap space

我真的不明白每循环时间的指数增长。在我至少能跑10圈之前。那里发生了什么事?在


Tags: 数据内存代码df时间learnkitspark
1条回答
网友
1楼 · 发布于 2024-10-01 07:51:35

我认为这个问题与Spark中懒惰的评估有关。由于我收集了所有的信息,pyspark数据帧rsmeMaeAll可能所有产生rsmeMaeAll所需的信息都在我试图计算输出的同时加载到了缓存中。在

基于这个想法,我重新构建了代码,这样Spark就不必再把所有步骤都放在中间了。此外,我集成了一个时间度量,并用两个变量重新构建了旧代码,使一个变量更接近新逻辑,每个变量的计算必须在每个循环结束时完成。在

解决办法如下:

for i in range(9):
    ti0 = time.time()
    df_features_train, df_features_test = randomizer(dataFiltered)
    rsmeMaeStep = rsmeMaeAnalysis(df_features_train,df_features_test)
    rsmeMaeAllpd = rsmeMaeAllpd.append(rsmeMaeStep.toPandas())
    print(rsmeMaeAllpd)
    ti1 = time.time()
    print "Time for loop", i, ":", ti1-ti0

在rsmeMaeAnalysis中,我刚刚计算了一个分析的结果,返回了它们,将它们转换成Pandas数据框,并在Pandas中收集了所有的结果。结果是每次循环都花费了差不多相同的时间,即使在20次循环之后,我也没有内存问题。前十个循环的时间如下:

41s ,42s ,44s ,40s ,43s ,43s ,40s ,39s ,40s ,40s

但后来我想确定的是,在pyspark数据帧中收集结果确实是个问题,因此我构建了一个尽可能接近pandas解决方案的代码,但要在pyspark数据帧中收集结果:

^{pr2}$

前八个循环的时间如下:

43s ,63s ,88s ,144s ,162s ,175s ,212s ,276s

在最初的版本中,仅使用时间测量,在第7次循环后出现内存不足错误之前,需要花费以下时间:

44s ,60s ,73s ,98s ,128s ,157s ,198s

最后,似乎懒惰求值导致产生rsmeMaeAll所需的大量信息同时加载到缓存中,尽管大多数信息在每个循环结束时都不相关。在

相关问题 更多 >