我正在运行此代码:
for (i <- Range(1, listOfCities.value.length)) {
val city = listOfCities.value(i)
logger.info(s"Started with city=$city")
val data = getDataFromQueries(redshiftConnector, sparkSession, city)
val transactions = data.map { pidData =>
pidData.p_list.trim.split(',')
}
val result: RDD[CRule[String]] =
run(sparkSession, transactions.rdd, numPartitions)
val resultWithCity = result.map { rule =>
(rule, city)
}
val df: DataFrame =
convertResultToDataframe(sparkSession, resultWithCity)
writeToRedshift(redshiftConnector, df, tableName)
}
每个结果都包含大量行。该代码适用于2-3个城市。但随后工人的记忆开始变得充满,程序变得非常缓慢。为什么内存被填满?垃圾收集没有发生或我的代码中是否有一些内存泄漏?我正在监控每个城市的内存需求,它每次都会翻倍,而不会在城市完工时摔倒。 每次迭代后我应该如何清理RAM?感谢
配置 - 3个m4.2xlarge worker,8个节点,30 GB RAM,6个执行器,每个4个核心
答案 0 :(得分:1)
在Spark中使用for循环是一个非常糟糕的做法,因为Spark优化器基本上是愚蠢的。
我的想法是首先将所有数据放入一个通用数据帧。所以基本上你会做以下事情:
var city = listOfCities.value(1)
var data = getDataFromQueries(redshiftConnector, sparkSession, city)
for (i <- Range(2, listOfCities.value.length)){
var city = listOfCities.value(i)
var data = data.unionAll(getDataFromQueries(redshiftConnector, sparkSession, city))
}
然后继续使用您的程序来进行&#34;大&#34;数据帧