尽管文件大小超过执行程序内存,但如何使用一个分区将数据帧写入 csv 文件
How can I write dataframe to csv file using one partition although the file size exceeds executors memory
我正在使用具有 2 个执行程序的 Apache Spark 独立集群,每个执行程序具有 1g 堆 space 和 8 个内核。
我将大小为 2.7Gb 的输入文件加载到数据帧中 df。这是使用 21 个任务成功完成的,也就是说我在整个集群中总共使用了 21 个分区。
现在我尝试仅使用 1 个分区将其写入 csv,这样我就可以在 1 个 csv 文件中获取所有记录。
df.coalesce(1).write.option("header","true").csv("output.csv")
我预计会出现 OOM 错误,因为执行程序的总可用内存少于 2.7Gb。但这并没有发生。
尽管数据大于单个分区,但我的任务如何不中断?幕后到底发生了什么?
原始 csv 文件的原始格式(基于文本,未压缩)大小为 2.7GB。当您使用 Spark 读取该文件时,它会根据默认为 128MB 的配置 spark.files.maxPartitionBytes
将数据分成多个分区。计算得出 2700MB / 128MB = 21 partitions
.
Spark 将数据保存在内存中,但保存在它自己的 storage format 中,称为“矢量化镶木地板”并使用默认压缩“lz4”。
因此,2.7GB 将适合提供的 1GB 内存。
请记住,并非 1GB 的所有 100% 都可用于数据 store/processing。执行器内存有一个清晰的设计,可以通过配置 spark.memory.fraction
和 spark.memory.storageFraction
进行配置。我在媒体上写了一篇关于 Executor Memory Layout.
的文章
这是一张有助于理解内存布局的图片:
我正在使用具有 2 个执行程序的 Apache Spark 独立集群,每个执行程序具有 1g 堆 space 和 8 个内核。
我将大小为 2.7Gb 的输入文件加载到数据帧中 df。这是使用 21 个任务成功完成的,也就是说我在整个集群中总共使用了 21 个分区。
现在我尝试仅使用 1 个分区将其写入 csv,这样我就可以在 1 个 csv 文件中获取所有记录。
df.coalesce(1).write.option("header","true").csv("output.csv")
我预计会出现 OOM 错误,因为执行程序的总可用内存少于 2.7Gb。但这并没有发生。
尽管数据大于单个分区,但我的任务如何不中断?幕后到底发生了什么?
原始 csv 文件的原始格式(基于文本,未压缩)大小为 2.7GB。当您使用 Spark 读取该文件时,它会根据默认为 128MB 的配置 spark.files.maxPartitionBytes
将数据分成多个分区。计算得出 2700MB / 128MB = 21 partitions
.
Spark 将数据保存在内存中,但保存在它自己的 storage format 中,称为“矢量化镶木地板”并使用默认压缩“lz4”。
因此,2.7GB 将适合提供的 1GB 内存。
请记住,并非 1GB 的所有 100% 都可用于数据 store/processing。执行器内存有一个清晰的设计,可以通过配置 spark.memory.fraction
和 spark.memory.storageFraction
进行配置。我在媒体上写了一篇关于 Executor Memory Layout.
这是一张有助于理解内存布局的图片: