我试图理解spark流(不是结构化流)的内部结构,特别是任务看到数据流的方式。我在这里复习一下scala中spark的源代码。我了解调用堆栈:
ExecutorCoarseGrainedBackend (main) -> Executor (launchtask) -> TaskRunner (Runnable).run() -> task.run(...)
我知道dstream实际上是rdd的hashmap,但我试图理解任务如何看待dstream。我知道KafkaSpark融合基本上有两种方法:
使用高级kafka消费api的基于接收器
在这里,接收任务以每一个批间隔(比如5秒)创建一个新的(微)批,其中包含5个分区(=>1秒块间隔),并将其交给下游的常规任务。
问:我们的例子是每5秒创建一个微博客;有正好5个分区,所有微批的所有这些分区都应该以完全相同的方式存储在下游,相同的常规任务是否作为一个长时间运行的任务重复使用每个微批(rdd)的相同分区id?例如。
如果t0时分区(p1,p2,p3,p4,p5)的ubatch1被分配给任务id(t1,t2,t3,t4,t5),那么t5时分区(p1',p2',p3',p4',p5')的ubatch2是否也被分配给同一组任务(t1,t2,t3,t4,t5),或者是否为ubatch2创建新任务(t6,t7,t8,t9,t10)?
如果是后者,那么当您已经知道有任务在做完全相同的事情并且可以作为长时间运行的任务重新使用时,每5秒就必须通过网络将新任务发送给执行者,这不是性能密集型的吗?
直接使用低级kafka消费api
在这里,kafka分区Map到spark分区,因此是一个任务。同样,考虑一个主题t的5个kafka分区,我们得到5个spark分区及其相应的任务。
问题:假设t0处的ubatch1具有分配给任务(t1、t2、t3、t4、t5)的分区(p1、p2、p3、p4、p5)。在时间t5,分区(p1',p2',p3',p4',p5')的ubatch2是否也被分配给同一组任务(t1,t2,t3,t4,t5),或者是否为ubatch2创建新任务(t6,t7,t8,t9,t10)?
1条答案
按热度按时间eh57zj3b1#
在阅读了apachespark的源代码之后,这里给出了一个明确的答案:
这是一个非常直观的方法。
我们使用sparkcontext中的sparkstreamingcontext(ssc)来创建和保存流上的转换序列,其形式为以foreachdstream数据流结尾的数据流dag,其中每个数据流都是rdd的容器,即hashmap
foreachdstream在ssc的dstream图中注册。
在ssc.start(-ing)执行时,jobscheduler将保存的计划放在事件循环上,该循环执行每一个ubatch间隔秒,为每个数据流创建/提取rdd,并从每个数据流中提取rdd,并将其保存在hashmap中以供corr.dstream在一段记忆持续时间内使用(例如,用于窗口)
在此过程中,创建以foreachdstream中指定的操作结尾的rdd dag,然后foreachdstream向dag调度器提交一个新作业。
此循环每间隔秒重复一次。