来自Kafka的Spark流媒体窗口操作

时间:2017-06-21 04:23:04

标签: window apache-kafka spark-streaming

我正在尝试探索来自Kafka的Spark流媒体。根据这个link,createDirectStream在kafka分区和Spark之间具有1:1的并行性。所以这意味着,如果有一个带有3个分区的Kafka主题,那么3个spark执行器将并行运行,每个都读取一个分区。

问题

  
      
  1. 假设在读取数据后我有一个窗口操作。窗口操作是否跨分区或在一个分区内应用窗口   分区即让我说我的批处理间隔是10秒和窗口间隔   是50多岁。窗口是否跨分区累积50s数据的数据   (如果每个分区有50个记录,每个分区有50个,窗口保持30个   记录)或每个分区并行50个数据(如果每个分区   每个50个记录有10个记录,窗口是否有10个记录)?

         

    伪代码:

         

    rdd = createDirectStream(...)

         

    rdd.window()

         

    rdd.saveAsTextFile()//这是将30条记录写入1个文件还是3个文件中   每个文件有10条记录?

  2.   
  
      
  1. 假设我有这个......

         

    伪码:

         

    rdd = createDirectStream()

         

    rdd.action1()

         

    rdd.window()

         

    rdd.action2()

         

    让我们说,我有3个kafka分区和3个执行器(每个读取一个   话题)。由于有2个动作,因此可以旋转2个作业。每个火花执行者   将具有RDD的分区并且action1并行应用。   现在对于action2,是否会使用相同的执行程序集(否则,   必须再次从卡夫卡读取数据 - 不是很好吗?

  2.   

1 个答案:

答案 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获取这些偏移并应用该操作。这不是问题所暗示的“坏”。这可以防止我们长时间存储中间数据,并允许我们保留数据的操作语义。

所以,是的,数据将再次被读取,这是一件好事。