Я запускаю 5 node Spark-кластер на AWS EMR каждый размером m3.xlarge(1 ведущий 4 slave-устройства). Я успешно прошел через сжатый CSV файл с размером 146 МБ bzip2 и получил совершенно агрегированный результат.
Теперь я пытаюсь обработать файл CSV размером ~ 5 ГБ bzip2 в этом кластере, но я получаю эту ошибку:
16/11/23 17:29:53 WARN TaskSetManager: потерянная задача 49.2 в стадии 6.0 (TID xxx, xxx.xxx.xxx.compute.internal): ExecutorLostFailure (исполнитель 16 вышел из-за одной из запущенных задач) Причина: Контейнер, убитый YARN, превышает пределы памяти. Используется 10,4 ГБ физической памяти 10,4 ГБ. Подумайте о том, как активировать spark.yarn.executor.memoryOverhead.
Я в замешательстве, почему я получаю ограничение памяти на 10,5 ГБ на кластере размером 75 ГБ (15 ГБ на 3 м.большой экземпляр)...
Вот моя конфигурация EMR:
[
{
"classification":"spark-env",
"properties":{
},
"configurations":[
{
"classification":"export",
"properties":{
"PYSPARK_PYTHON":"python34"
},
"configurations":[
]
}
]
},
{
"classification":"spark",
"properties":{
"maximizeResourceAllocation":"true"
},
"configurations":[
]
}
]
Из того, что я прочитал, установка свойства maximizeResourceAllocation
должна сообщить EMR, чтобы настроить Spark для полного использования всех ресурсов, доступных в кластере. То есть, у меня должно быть ~ 75 ГБ памяти... Так почему я получаю ошибку ограничения памяти на 10,5 ГБ?
Вот код, который я запускаю:
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 для агрегирования данных.
Он начинается с нескольких из этих ошибок и останавливает увеличение количества той же ошибки.
Я пробовал запускать искра-submit с помощью - conf spark.yarn.executor.memoryOverhead, но это также не решает проблему.