我正在使用Spark 2.3.1 PySpark(AWS EMR)
我遇到内存错误:
容器因超出内存限制而被YARN杀死 考虑提高spark.yarn.executor.memoryOverhead
我输入了160个文件,每个文件大约350-400 MB,每个文件都是CSV Gzip格式。
要读取csv.gz文件(使用通配符),我将使用此Pyspark
dfgz = spark.read.load("s3://mybucket/yyyymm=201708/datafile_*.csv.gz",
format="csv", sep="^", inferSchema="false", header="false", multiLine="true", quote="^", nullValue="~", schema="id string,...."))
要保存数据框,请使用此(PySpark)
(dfgz
.write
.partitionBy("yyyymm")
.mode("overwrite")
.format("parquet")
.option("path", "s3://mybucket/mytable_parquet")
.saveAsTable("data_test.mytable")
)
一行代码可保存所有160个文件。
我尝试了1个文件,但效果很好。
所有160个文件(csv.gzip)的总大小约为64 GB。
每个文件以纯CSV格式显示,解压缩后约为3.5 GB。我假设Spark可以将RAM中的每个文件解压缩,然后将其转换为RAM中的Parquet?
我想将每个csv.gzip文件转换为Parquet格式,即,我希望输出160个Parquet文件(理想情况下)。
该任务运行了一段时间,似乎为每个CSV.GZ文件创建了一个Parquet文件。一段时间后,它总是失败,并出现纱线存储错误。
我为执行程序的memory和memoryOverhead尝试了各种设置,所有结果均未更改-作业始终失败。我尝试了高达1-8 GB的memoryOverhead和8G的执行器内存。
除了将输入的160个文件的工作负载手动分解为许多小的工作负载外,我还能做什么? 我是否需要一个总RAM容量远远大于64 GB的Spark集群? 我使用4个从属节点,每个从属节点具有8个CPU和每个节点(从属节点)16 GB,再加上一个4个CPU和8 GB RAM的主节点。
这是我(正在处理)少于64 GB的输入gzip csv文件,但是这些文件的大小平均为350-400 MB,因此我不明白为什么Spark会抛出内存错误,因为它可以轻松处理这些错误每个执行程序一次只能发送1个文件,将其丢弃并移至下一个文件。它似乎无法以这种方式工作。我感觉它正在尝试将所有输入的csv.gzip文件加载到内存中,但我无从得知(我对Spark 2.3.1还是很陌生)。
最新更新:我设法使其与以下内存配置一起使用:
4个从属节点,每个8个CPU和16 GB RAM 1个主节点,4个CPU和8 GB的RAM:
spark maximizeResourceAllocation false
spark-defaults spark.driver.memoryOverhead 1g
spark-defaults spark.executor.memoryOverhead 2g
spark-defaults spark.executor.instances 8
spark-defaults spark.executor.cores 3
spark-defaults spark.default.parallelism 48
spark-defaults spark.driver.memory 6g
spark-defaults spark.executor.memory 6g
不用说-我无法解释为什么此配置有效! 同样,这花费了2个小时以上的时间来处理64 GB的gzip数据,即使对于一个小型的4 + 1节点群集(总共具有32 + 4 CPU和64 + 8 GB RAM)来说,这似乎也很慢。也许S3是瓶颈。 FWIW我只是没想到要微管理数据库集群以进行内存,磁盘I / O或CPU分配。
更新2:
我只是在具有相同配置的同一群集上运行了另一个负载,较小的负载是129个相同大小的文件,并且此负载因相同的Yarn内存错误而失败。 我对Spark 2.3.1内存管理感到非常失望。
谢谢您的指导