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

Spark streaming. Reading in parallel from Kafka is causing repeated data

我使用以下代码创建了 6 个输入 DStream,这些 DStream 使用直接方法从 Kafka 的 6 分区主题读取,我发现即使为流指定相同的组 ID,我也会重复 6 次数据。如果我只创建 3 个 DStream,我会重复 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)

我哪里做错了?

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

如果python中相同,则不需要启动n个流。启动一个流,Spark 将处理分区到 executors/tasks 本身的分配。

在直接方法中,您不应从一个主题创建多个流。

来自documentation

Simplified Parallelism: No need to create multiple input Kafka streams and union them. With directStream, Spark Streaming will create as many RDD partitions as there are Kafka partitions to consume, which will all read data from Kafka in parallel. So there is a one-to-one mapping between Kafka and RDD partitions, which is easier to understand and tune.

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

基本上,当您创建 Dstream 时,通过共享 load.By 默认值,Kafka 主题被分配以加快多个 receivers/consumers 的分发,一个接收器将 运行 并从每个 Kafka 主题接收数据通过接收器线程(Java 线程)并行分区到 Dstream 分区。如果您为一个主题创建 6 个 Dstreams 意味着同一主题有 6 个接收者这并不意味着每个部分的每个 Dstream。每个接收者获得每个馈送一次,因此每个馈送获得 6 次。