火花流。从Kafka并行读取会导致重复数据

时间:2016-11-22 08:59:01

标签: python apache-spark streaming apache-kafka

我创建了以下代码,它创建了6个输入DStream,它使用直接aproach从Kafka读取6个分区主题,我发现即使为流指定相同的组ID,我也会重复6次数据。如果我只创建3个DStreams,我会重复数据3次等等......

numStreams = 6
kafkaStreams = [KafkaUtils.createDirectStream(ssc, ["send6partitions"], {
  "metadata.broker.list": brokers,
  "fetch.message.max.bytes": "20971520",
  "spark.streaming.blockInterval" : "2000ms",
  "group.id" : "the-same"},
  valueDecoder = decodeValue, keyDecoder = decode_key) for _ in range (numStreams)]

kvs = ssc.union(*kafkaStreams)

我在这里做错了什么?

3 个答案:

答案 0 :(得分:1)

我不熟悉Python,但Spark Scala中的Direct Stream不提交任何偏移。因此,如果您打开一个流n次而不提交任何读取消息的偏移量,您的消费者将从头开始。

如果在python中相同,则不需要启动n个流。启动一个流,Spark将处理分区到执行程序/任务本身的分配。

答案 1 :(得分:1)

在Direct方法中,你不应该从一个主题创建许多DStream。

来自documentation

  

简化并行:无需创建多个输入Kafka流   并结合他们。使用directStream,Spark Streaming将创建尽可能多的内容   RDD分区,因为有Kafka分区要使用,这将是   所有人都从Kafka并行读取数据。所以有一对一的映射   在Kafka和RDD分区之间,这更容易理解和   调。

所以只需创建一个DStream,Spark就会使用所有Kafka分区:)

答案 2 :(得分:1)

基本上,通过共享负载,Kafka主题可以分配给多个接收者/消费者更快的分发。默认情况下,当您创建Dstream时,一个接收者将通过接收者线程并行地运行和接收来自每个Kafka主题分区到Dstream分区的数据(Java)线)。如果要为一个主题创建6个Dstream,则表示同一主题的6个接收器并不意味着每个端口的每个Dstream。每个接收器一次获得每个馈送,因此每次馈送获得6次。