Spark:如何加速foreachRDD?

时间:2017-03-03 15:18:39

标签: apache-spark spark-streaming

我们有一个Spark流应用程序,它可以提取数据 @ 10,000 / sec ...我们在DStream上使用foreachRDD操作(因为除非在DStream上找到输出操作,否则spark不会执行)

因此我们必须使用这样的foreachRDD输出操作,它需要 3小时 ...来编写单一数据(10,000)

CodeSnippet 1:

requestsWithState.foreachRDD { rdd =>

     rdd.foreach {
     case (topicsTableName, hashKeyTemp, attributeValueUpdate) => {          
          val client = new AmazonDynamoDBClient()
          val request = new UpdateItemRequest(topicsTableName, hashKeyTemp, attributeValueUpdate)
          try client.updateItem(request)

        catch {
            case se: Exception => println("Error executing updateItem!\nTable ", se)
         }
        }
        case null =>
      }
    }
  } 

所以我认为foreachRDD中的代码可能是问题,所以请注意它需要花多少时间.... 令我惊讶的是......即使在foreachRDD中使用了nocode它仍然运行了3个小时

CodeSnippet 2:

requestsWithState.foreachRDD { 
rdd => rdd.foreach { 
// No code here still takes a lot of time ( there used to be code but removed it to see if it's any faster without code) // 
 }
}  

请告诉我们,如果我们遗漏了任何内容或其他方法来执行此操作,因为我理解没有DStream上的输出操作火花流应用程序将无法运行..此时我无法使用其他输出操作...

注意:要隔离问题并确保发电机代码没有问题...我用空循环运行.....看起来就像foreachRDD在迭代一个巨大的记录集时自己很慢在@ 10,000 /秒...而不是发电机代码为空的foreachRDD和发电机代码花了相同的时间......

ScreenShot显示执行的所有阶段和 foreachRDD 所花费的时间,即使它是循环播放且内部没有代码

foreachRDD空循环所花费的时间

**Time taken by the foreachRDD empty loop**

foreachRDD空循环的9个工作节点中大型运行任务的任务分配...

**Task Distribution among 9 worker nodes for the foreachRDD empty loop**

2 个答案:

答案 0 :(得分:1)

我知道已经晚了,但是如果您想听听,我有一些猜测可能会为您提供一些见识。

不是rdd.foreach中的代码花费很长时间,而是rdd.foreach之前的代码,它生成rdd。 转换是惰性的,直到您使用结果,spark才会对其进行计算。 当代码在rdd.foreach中运行时,sp​​ark进行计算并生成数据行。rdd.foreach循环中的代码仅处理结果。 您可以通过注释rdd.foreach

进行检查
requestsWithState.foreachRDD { 
  //rdd => rdd.foreach { 
  // No code here still takes a lot of time ( there used to be code but removed it to //see if it's any faster without code) 
  //}
} 

我想它将非常快,因为不会进行任何计算。 或者您可以将转换更改为非常简单的转换,它也会很快。 它不能解决您的问题,但是如果我说对了,它将帮助您找到问题所在。

答案 1 :(得分:0)

您是否尝试过如下所示的无循环操作?

//requestsWithState.foreachRDD {  
  //rdd => rdd.foreach {  
  // No code here //  
  // } 
//}

foreachRDD花费的时间而不是其中的代码。请注意,它是foreach而不是for。无论内部是否有代码,它都会运行n次。

有效测试可用于性能测试:

https://tech.ovoenergy.com/spark-streaming-in-production-testing/