在这种情况下
val dStream : Stream[_] =
dStream.foreachRDD(a => ... )
dStream.foreachRDD(b => ... )
做foreach方法:
我想知道,因为我想在数据库插入后提交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 =>)?
答案 0 :(得分:4)
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,则可以并行执行。因此,请确保您的设置正确无误,才能引起您所需的行为。