在foreachRDD中使用变量时是否需要使用广播变量?

时间:2018-04-17 10:36:29

标签: scala apache-spark apache-kafka

在我的代码中,我订阅了一个Kafka流并在函数中处理每个RDD:

  val myStream = KafkaUtils.createDirectStream[K, V](
      streamingContext,
      PreferConsistent,
      Subscribe[K, V](topics, consumerConfig)
    )

  val myMap: Map[ObjA, ObjB] = getMyMap() // This is the variable I want to access in 'process'

  def process(record: (RDD[ConsumerRecord[String, String]], Time)): Unit = record match {

     // Code that uses myMap.get("key")

  }

  myStream.foreachRDD((x, y) => process((x, y)))

我读过有关Spark and Kafka integration patterns的帖子。据我所知,foreachRDD在驱动程序上本地执行,但随后任何内部循环都会分发到集群节点。这是否意味着我 broadcast myMap出于性能原因?

2 个答案:

答案 0 :(得分:1)

  

这是否意味着我应该出于性能原因广播myMap?

好:

因为变量在多个任务中重复使用,所以广播中有一个值,特别是如果数据足够大以增加显着的开销。

如果没有,为了更好的可读性,坚持使用闭包序列化可能是优先考虑的(我承认这是一个偏好的问题)。

答案 1 :(得分:1)

  

然后将任何内部循环分发到集群节点

它不是任何内循环"它是分布式的,但是在RDD上运行。

因此,这取决于myMap.get("key")process的使用情况。例如。这是一个广播毫无意义的例子:

def process(record: (RDD[ConsumerRecord[String, String]], Time)): Unit = record match {
  case (rdd, _) => rdd.take(10).filter(/* do something using myMap */)
}