我有一个大约200-600 gb数据的数据框,我正在阅读,操作,然后使用弹性地图缩小群集上的spark shell (scala)
写入csv。即使在8小时后,写入CSV的Spark也会失败< / p>
这是我写给csv的方式:
result.persist.coalesce(20000).write.option("delimiter",",").csv("s3://bucket-name/results")
结果变量是通过来自其他一些数据帧的混合列创建的:
var result=sources.join(destinations, Seq("source_d","destination_d")).select("source_i","destination_i")
现在,我能够在大约22分钟内读取它所基于的csv数据。在同一个程序中,我还可以在8分钟内将另一个(较小的)数据帧写入csv。但是,对于此result
数据帧,它需要8个多小时但仍然失败...说其中一个连接已关闭。
我也在13 x c4.8xlarge instances on ec2
上运行这个工作,每个工作36个核心和60 GB的ram,所以我认为我有能力写入csv,特别是8小时后。
许多阶段需要重试或任务失败,我无法弄清楚我做错了什么或为什么这么长时间。我可以从Spark UI看到它甚至从未进入写入CSV阶段并忙于持续阶段,但没有持久性功能,它仍然在8小时后失败。有任何想法吗?非常感谢帮助!
更新
我运行了以下命令将result
变量重新分区为66K分区:
val r2 = result.repartition(66000) #confirmed with numpartitions
r2.write.option("delimiter",",").csv("s3://s3-bucket/results")
然而,即使在几个小时后,工作仍然失败。我到底做错了什么?
请注意,我正在通过spark-shell yarn --driver-memory 50G
更新2:
我尝试先使用persist执行写操作:
r2.persist(StorageLevel.MEMORY_AND_DISK)
但我有很多阶段失败,返回a,Job aborted due to stage failure: ShuffleMapStage 10 (persist at <console>:36) has failed the maximum allowable number of times: 4. Most recent failure reason: org.apache.spark.shuffle.MetadataFetchFailedException: Missing an output location for shuffle 3'
或说Connection from ip-172-31-48-180.ec2.internal/172.31.48.180:7337 closed
答案 0 :(得分:1)
我可以从Spark UI看到它甚至没有写入CSV 阶段,并忙于坚持阶段,但没有坚持 功能它在8小时后仍然失败。有什么想法吗?
是FetchFailedException
,即无法获取随机块
由于你能够处理小文件,只有大量数据失败... 我强烈感觉没有足够的分区。
首先是验证/打印source.rdd.getNumPartitions()
。和destinations.rdd.getNumPartitions()
。和result.rdd.getNumPartitions()
。
您需要在加载数据后重新分区,以便将数据(通过shuffle)分区到群集中的其他节点。这将为您提供快速处理失败所需的并行性
此外,验证应用的其他配置... 打印所有这样的配置,根据需要将它们调整为正确的值。
sc.getConf.getAll
答案 1 :(得分:0)
在加入之前重新分配源和目标,分区数量使每个分区为10MB - 128MB(尝试调整),没有必要使它20000(imho太多)。 然后通过这两列连接然后写入,而不进行重新分区(即输出分区应该与连接前的重新分区相同)
如果你还有问题,请在转换为数据帧到rdd之后尝试做同样的事情(apis之间存在一些差异,特别是关于重新分区,键值rdds等)