我正在尝试探索来自Kafka的Spark流媒体。根据这个link,createDirectStream在kafka分区和Spark之间具有1:1的并行性。所以这意味着,如果有一个带有3个分区的Kafka主题,那么3个spark执行器将并行运行,每个都读取一个分区。
问题
- 醇>
假设在读取数据后我有一个窗口操作。窗口操作是否跨分区或在一个分区内应用窗口 分区即让我说我的批处理间隔是10秒和窗口间隔 是50多岁。窗口是否跨分区累积50s数据的数据 (如果每个分区有50个记录,每个分区有50个,窗口保持30个 记录)或每个分区并行50个数据(如果每个分区 每个50个记录有10个记录,窗口是否有10个记录)?
伪代码:
rdd = createDirectStream(...)
rdd.window()
rdd.saveAsTextFile()//这是将30条记录写入1个文件还是3个文件中 每个文件有10条记录?
- 醇>
假设我有这个......
伪码:
rdd = createDirectStream()
rdd.action1()
rdd.window()
rdd.action2()
让我们说,我有3个kafka分区和3个执行器(每个读取一个 话题)。由于有2个动作,因此可以旋转2个作业。每个火花执行者 将具有RDD的分区并且action1并行应用。 现在对于action2,是否会使用相同的执行程序集(否则, 必须再次从卡夫卡读取数据 - 不是很好吗?
答案 0 :(得分:1)
问)如果有一个带有3个分区的Kafka主题,那么3个spark执行器将并行运行,每个都读取一个分区。
更具体地说,将向Spark集群提交3个任务,每个分区一个。 哪里这些任务的执行取决于您的群集拓扑和位置设置,但通常您可以认为这3个任务将并行运行。
Q)假设我在读取数据后进行窗口操作。窗口操作是否跨分区或在一个分区内应用窗口?
Spark的基本模型和Spark Streaming的传递性是在抽象(Spark的RDD / Datasets,Spark Streaming的DStream)上声明操作,并且在执行级别,这些操作将以分布式方式应用,使用数据的本机分区。
((我不确定问题在“跨分区或在一个分区内”之间的区别。窗口将按照分区保留。操作将根据自己的语义应用。例如,每个分区将应用map
操作,而count
操作将首先应用于每个分区,然后合并为一个结果。))
关于伪代码:
val dstream = createDirectStream(..., Seconds(30))
dstream.window(Seconds(600)) // this does nothing as the new dstream is not referenced any further
val windowDstream = dstream.window(timePeriod) // this creates a new Windowed DStream based on the base DStream
dstream.saveAsTextFiles() // this writes using the original streaming interval (30 seconds). It will write 1 logical file in the distributed file system with 3 partitions
windowDstream.saveAsTextFiles() // this writes using the windowed interval (600 seconds). It will write 1 logical file in the distributed file system with 3 partitions.
鉴于此代码(注意命名更改!):
val dstream = createDirectStream(...)
dstream.action1()
val windowDStream = dstream.window(...)
windowDStream.action2()
对于action2,是否会使用相同的执行程序集(否则,必须再次从Kafka读取数据 - 不好)?
对于直接流模型,每个时间间隔的RDD不包含任何数据,只包含偏移(offset-start, offset-end)
。只有在应用操作时才会读取数据。
Window (1-3) = (offset1-start, offset1-end), (offset2-start, offset2-end), (offset3-start, offset3-end)
。当一个动作应用于该窗口时,将从Kafka获取这些偏移并应用该操作。这不是问题所暗示的“坏”。这可以防止我们长时间存储中间数据,并允许我们保留数据的操作语义。
所以,是的,数据将再次被读取,这是一件好事。