火花流是否并行运行多个foreach

时间:2016-05-24 13:45:09

标签: scala apache-spark apache-kafka

在这种情况下

val dStream : Stream[_] = 
dStream.foreachRDD(a => ... )
dStream.foreachRDD(b => ... )

做foreach方法:

  1. 并行运行?
  2. 按顺序运行,但没有特定的顺序?
  3. foreachRDD(b =>)之前的foreachRDD(a =>)?
  4. 我想知道,因为我想在数据库插入后提交kafka偏移量。 (并且db连接器仅提供" foreach"插入)

    val dStream : Stream[_] = ...().cache()
    dStream.toDb // consume the stream
    dStream.foreachRDD(b => //commit offset ) //consume the stream but after the db insert
    

    在火花用户界面中,它看起来有订单,但我不确定它是否可靠。

    编辑:如果foreachRDD(a =>)失败,是否仍然执行foreachRDD(b =>)?

2 个答案:

答案 0 :(得分:4)

自Spark 0.9.0以来,

DStream.foreach已被弃用。您希望等效的DStream.foreachRDD开头。

Spark DAG中的阶段是按顺序执行的,因为一个变换的输出通常也是图中下一个变换的输入,但在您的示例中并非如此。

在内部,RDD被划分为多个分区。每个分区都在不同的工作线程上运行,该工作线程可供集群管理器使用。在您的示例中,DStream.foreach(a => ...)将在DStream.foreach(b => ...)之前执行,但foreach内的执行将与正在迭代的内部RDD并行运行。

  

我想知道,因为我想在a之后提交kafka偏移量   数据库插入。

DStream.foreachRDD是输出转换,这意味着它将使Spark实现图形并开始执行。您可以放心地假设数据库的插入将在执行第二个foreach之前结束,但请记住,您的第一个foreach将在{{1}中并行更新数据库的foreach分区}。

答案 1 :(得分:0)

多个DStream.foreachRDD不能保证至少在spark-streaming-2.4.0之前顺序执行。在JobScheduler类中查看以下代码:

class JobScheduler(val ssc: StreamingContext) extends Logging {

  // Use of ConcurrentHashMap.keySet later causes an odd runtime problem due to Java 7/8 diff
  // https://gist.github.com/AlainODea/1375759b8720a3f9f094
  private val jobSets: java.util.Map[Time, JobSet] = new ConcurrentHashMap[Time, JobSet]
  private val numConcurrentJobs = ssc.conf.getInt("spark.streaming.concurrentJobs", 1)
  private val jobExecutor =
    ThreadUtils.newDaemonFixedThreadPool(numConcurrentJobs, "streaming-job-executor")

JobExecutor是一个线程池,并且如果将“ spark.streaming.concurrentJobs”设置为大于1的数字,并且如果有足够的spark-executor,则可以并行执行。因此,请确保您的设置正确无误,才能引起您所需的行为。