jvm 我如何使用一个分区将 Dataframe 写入csv文件,尽管文件大小超过了执行器内存

vql8enpb  于 2022-11-07  发布在  其他
关注(0)|答案(1)|浏览(207)

我正在使用Apache Spark独立集群,其中有2个执行器,每个执行器都有1g的堆空间和8个内核。
我将大小为2.7Gb的输入文件加载到一个 Dataframedf中。这是使用21个任务成功完成的,也就是说,我在整个集群中总共使用了21个分区。
现在我试着只使用1个分区将其写入csv,这样我就可以在1个csv文件中获得所有记录。

df.coalesce(1).write.option("header","true").csv("output.csv")

我期望得到一个OOM错误,因为一个执行器的总可用内存小于2. 7GB。但这并没有发生。
为什么我的任务在数据比一个分区大的情况下没有中断?这里到底发生了什么?

relj7zay

relj7zay1#

原始csv文件的原始格式(基于文本,没有压缩)大小为2.7GB。当你用Spark读取该文件时,它会根据配置spark.files.maxPartitionBytes(默认为128 MB)将数据分割成多个分区。计算一下,结果是2700MB / 128MB = 21 partitions
Spark将数据保存在内存中,但保存在它自己的storage format中,称为“矢量化Parquet”,并使用默认压缩“lz 4”。
因此,2.7GB将适合提供的1GB内存。
请记住,并不是所有的1GB都可用于数据存储/处理。有一个明确的设计,以执行器内存,可以配置的配置spark.memory.fractionspark.memory.storageFraction。我写了一篇文章,在媒体上的Executor Memory Layout
以下图片有助于理解内存布局:

相关问题