我正在使用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。但这并没有发生。
为什么我的任务在数据比一个分区大的情况下没有中断?这里到底发生了什么?
1条答案
按热度按时间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.fraction
和spark.memory.storageFraction
。我写了一篇文章,在媒体上的Executor Memory Layout。以下图片有助于理解内存布局: