内存被Spark Scala填满

时间:2017-03-02 11:17:37

标签: scala apache-spark memory optimization

我正在运行此代码:

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个核心

1 个答案:

答案 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;数据帧