Apache spark &引用;因超过内存限制而被纱线杀死的容器。使用10.4 GB的10.4 GB物理内存“;在具有75GB内存的EMR群集上
我在AWS EMR上运行一个5节点的Spark群集,每个大小为m3.xlarge(1个主节点4个从节点)。我成功地运行了一个146Mb的bzip2压缩CSV文件,最终得到了一个完美的聚合结果 现在,我试图在此群集上处理~5GB bzip2 CSV文件,但收到以下错误: 16/11/23 17:29:53警告TaskSetManager:在阶段6.0(TID xxx,xxx.xxx.xxx.compute.internal)中丢失任务49.2:执行器丢失失败(执行器16因一个正在运行的任务而退出)原因:容器因超过内存限制而被纱线杀死。使用10.4 GB的10.4 GB物理内存中的10.4 GB。考虑提升火花。纱线。执行器。内存开销。 我不明白为什么在一个~75GB的集群上会有~10.5GB的内存限制(每3m.xlarge实例15GB) 这是我的EMR配置:Apache spark &引用;因超过内存限制而被纱线杀死的容器。使用10.4 GB的10.4 GB物理内存“;在具有75GB内存的EMR群集上,apache-spark,emr,amazon-emr,bigdata,Apache Spark,Emr,Amazon Emr,Bigdata,我在AWS EMR上运行一个5节点的Spark群集,每个大小为m3.xlarge(1个主节点4个从节点)。我成功地运行了一个146Mb的bzip2压缩CSV文件,最终得到了一个完美的聚合结果 现在,我试图在此群集上处理~5GB bzip2 CSV文件,但收到以下错误: 16/11/23 17:29:53警告TaskSetManager:在阶段6.0(TID xxx,xxx.xxx.xxx.compute.internal)中丢失任务49.2:执行器丢失失败(执行器16因一个正在运行的任务而退出)
[
{
"classification":"spark-env",
"properties":{
},
"configurations":[
{
"classification":"export",
"properties":{
"PYSPARK_PYTHON":"python34"
},
"configurations":[
]
}
]
},
{
"classification":"spark",
"properties":{
"maximizeResourceAllocation":"true"
},
"configurations":[
]
}
]
根据我所读的内容,设置maximizeResourceAllocation
属性应该告诉EMR配置Spark以充分利用集群上的所有可用资源。我应该有大约75GB的可用内存。。。那么,为什么会出现~10.5GB内存限制错误?
以下是我正在运行的代码:
def sessionize(raw_data, timeout):
# https://www.dataiku.com/learn/guide/code/reshaping_data/sessionization.html
window = (pyspark.sql.Window.partitionBy("user_id", "site_id")
.orderBy("timestamp"))
diff = (pyspark.sql.functions.lag(raw_data.timestamp, 1)
.over(window))
time_diff = (raw_data.withColumn("time_diff", raw_data.timestamp - diff)
.withColumn("new_session", pyspark.sql.functions.when(pyspark.sql.functions.col("time_diff") >= timeout.seconds, 1).otherwise(0)))
window = (pyspark.sql.Window.partitionBy("user_id", "site_id")
.orderBy("timestamp")
.rowsBetween(-1, 0))
sessions = (time_diff.withColumn("session_id", pyspark.sql.functions.concat_ws("_", "user_id", "site_id", pyspark.sql.functions.sum("new_session").over(window))))
return sessions
def aggregate_sessions(sessions):
median = pyspark.sql.functions.udf(lambda x: statistics.median(x))
aggregated = sessions.groupBy(pyspark.sql.functions.col("session_id")).agg(
pyspark.sql.functions.first("site_id").alias("site_id"),
pyspark.sql.functions.first("user_id").alias("user_id"),
pyspark.sql.functions.count("id").alias("hits"),
pyspark.sql.functions.min("timestamp").alias("start"),
pyspark.sql.functions.max("timestamp").alias("finish"),
median(pyspark.sql.functions.collect_list("foo")).alias("foo"),
)
return aggregated
spark_context = pyspark.SparkContext(appName="process-raw-data")
spark_session = pyspark.sql.SparkSession(spark_context)
raw_data = spark_session.read.csv(sys.argv[1],
header=True,
inferSchema=True)
# Windowing doesn't seem to play nicely with TimestampTypes.
#
# Should be able to do this within the ``spark.read.csv`` call, I'd
# think. Need to look into it.
convert_to_unix = pyspark.sql.functions.udf(lambda s: arrow.get(s).timestamp)
raw_data = raw_data.withColumn("timestamp",
convert_to_unix(pyspark.sql.functions.col("timestamp")))
sessions = sessionize(raw_data, SESSION_TIMEOUT)
aggregated = aggregate_sessions(sessions)
aggregated.foreach(save_session)
基本上,只有窗口和groupBy来聚合数据
它从这些错误中的一些开始,逐渐停止相同错误数量的增加
我已经尝试使用--conf spark.warn.executor.memoryOverhead运行spark submit,但这似乎也不能解决问题。请参见
我在一个巨大的集群中遇到了同样的问题,我现在正在工作。将内存添加到辅助进程将无法解决此问题。有时,进程内聚合spark将使用比现有内存更多的内存,spark作业将开始使用堆外内存
一个简单的例子是:
如果您有一个数据集需要reduceByKey
,它有时会在一个worker中释放比另一个worker更多的数据,并且如果该数据超出了一个worker的内存,则会收到该错误消息
添加选项spark.warn.executor.memoryOverhead
将有助于您将工作程序使用的内存设置为50%(仅用于测试,看看是否有效,您可以通过更多测试添加更少的内存)
但您需要了解Spark如何处理集群中的内存分配:
warn site.xml
中将warn.nodemanager.vmem check enabled
设置为false
,我们的容器不再被杀死,应用程序似乎按预期工作
通过进一步研究,我找到了为什么会发生这种情况的答案:
由于在Centos/RHEL 6上,由于操作系统的行为,虚拟内存的分配非常激烈,因此应禁用虚拟内存检查器或将warn.nodemanager.vmem-pmem-ratio增加到相对较大的值
该页面有一个指向IBM提供的非常有用的页面的链接:
总之,glibc>2.10更改了其内存分配。尽管分配的大量虚拟内存并不是世界末日,但它不适用于纱线的默认设置
您也可以在hadoop env.sh
中将MALLOC_ARENA_MAX
环境变量设置为较低的数值,而不是将warn.nodemanager.vmem check enabled
设置为false。此错误报告提供了有用的信息
[{
"Classification": "yarn-site",
"Properties": {
"yarn.nodemanager.vmem-check-enabled": "false"
}
}]
classification=yarn-site,properties=[yarn.nodemanager.vmem-check-enabled=false]
RWS_PER_PARTITION = 1000
input_df = spark.write.csv("file_uri", *other_args)
total_rows = input_df.count()
original_num_partitions = input_df.getNumPartitions()
numPartitions = max(total_rows/RWS_PER_PARTITION, original_num_partitions)
input_df = input_df.repartition(numPartitions)