apache-spark - Spark:未能将数据帧保存到 Google Cloud Storage
问题描述
Spark 作业的最后阶段是以 avro 格式将 37Gb 的数据保存到 GCS 存储桶。Spark 应用在 Dataproc 上运行。
我的集群包括:15 个 4 核和 15Gb RAM 的工作人员,1 个 4 核和 15Gb RAM 的主服务器。
我使用以下代码:
df.write.option("forceSchema", schema_str) \
.format("avro") \
.partitionBy('platform', 'cluster') \
.save(f"gs://{output_path}")
在 Spark 运行失败任务之一的 4 次尝试中,我得到的错误代码是:
1/4. java.lang.StackOverflowError
2/4. Job aborted due to stage failure: Task 29 in stage 13.0 failed 4 times, most recent failure: Lost task 29.3 in stage 13.0 (TID 3048, ce-w1.internal, executor 17): ExecutorLostFailure (executor 17 exited caused by one of the running tasks) Reason: Container from a bad node: container_1607696154227_0002_01_000028 on host: ce-w1.internal. Exit status: 50. Diagnostics: [2020-12-11 15:46:19.880]Exception from container-launch.
Container id: container_1607696154227_0002_01_000028
Exit code: 50
[2020-12-11 15:46:19.881]Container exited with a non-zero exit code 50. Error file: prelaunch.err.
Last 4096 bytes of prelaunch.err :
Last 4096 bytes of stderr :
readOrdinaryObject(ObjectInputStream.java:2187)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1667)
at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:2405)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:2329)
3/4. java.lang.StackOverflowError
4/4. Job aborted due to stage failure: Task 29 in stage 13.0 failed 4 times, most recent failure: Lost task 29.3 in stage 13.0 (TID 3048, ce-w1.internal, executor 17): ExecutorLostFailure (executor 17 exited caused by one of the running tasks) Reason: Container from a bad node: container_1607696154227_0002_01_000028 on host: ce-w1.internal. Exit status: 50. Diagnostics: [2020-12-11 15:46:19.880]Exception from container-launch.
Container id: container_1607696154227_0002_01_000028
Exit code: 50
[2020-12-11 15:46:19.881]Container exited with a non-zero exit code 50. Error file: prelaunch.err.
Last 4096 bytes of prelaunch.err :
Last 4096 bytes of stderr :
readOrdinaryObject(ObjectInputStream.java:2187)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1667)
at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:2405)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:2329)
Spark UI 给了我这个:
从 UI 可以明显看出,数据分发正在发生某些事情,但重新分区会产生相同的 StackOverflow 错误。
所以我想问的两个问题:
如何在 StackOverflow 错误的上下文中解码消息“容器预启动错误”?
尽管数据分布相同,为什么作业中的其他操作可以安全运行?
解决方案
问题不是由于您的集群容量,而是由于您正在使用 avro 格式并且您正在强制 spark 编写新模式,同时保存尝试不使用后定义模式,它会起作用。例如,如果您想在通过 withColumn 保存之前尝试模式,请检查 shuffle 的数量。
df.write.format("avro") \
.partitionBy('platform', 'cluster') \
.save(f"gs://{output_path}")
推荐阅读
- utf-8 - 'utf-8' 编解码器无法解码位置 3057 中的字节 0x9c:导入某些 python 库时出现无效的起始字节错误
- rust - 是否可以使用 trait 方法而不将其纳入范围?
- git - 如何将一个分支合并到一个变化很大并且几年没有合并的分支
- arrays - 修改给定数组后的空间复杂度是多少?
- python - 使用Sqlalchemy查询time1和time2之间的数据时出现一些问题
- xml - powershell 提取两个 xml 标签之间的值并保存到 txt 文件
- excel - 使用 phpspreadsheet 时,从模板 xlsx 文件更改了条形图和圆环图的颜色和样式
- c# - 如何在 Gmail 中发送电子邮件,以便在 Google 日历中自动创建活动
- java - 使用 Firebase 在 Android 中进行 Twitter 身份验证
- vue.js - 方法“watch”在组件定义中具有类型“object”。您是否正确引用了该函数?