Spark Streaming:Spark Structured Streaming中不允许使用Kafka组ID

时间:2017-09-20 03:19:28

标签: apache-spark pyspark apache-kafka spark-structured-streaming

我正在PySpark中编写Spark结构化流应用程序来读取Kafka的数据。

但是,Spark的当前版本是2.1.0,它不允许我将组ID设置为参数,并为每个查询生成唯一的id。但Kafka连接是基于组的授权,需要预先设置的组ID。

因此,是否有任何解决方法可以建立连接而无需将Spark更新为2.2 ,因为我的团队不需要它。

我的代码:

if __name__ == "__main__":
    spark = SparkSession.builder.appName("DNS").getOrCreate()
    sc = spark.sparkContext
    sc.setLogLevel("WARN")

    # Subscribe to 1 topic
    lines = spark.readStream.format("kafka").option("kafka.bootstrap.servers", "host:9092").option("subscribe", "record").option('kafka.security.protocol',"SASL_PLAINTEXT").load()
    print(lines.isStreaming) #print TRUE
    lines.selectExpr("CAST(value AS STRING)")
    # Split the lines into words
    words = lines.select(
    explode(
        split(lines.value, " ")
        ).alias("word")
    )
    # Generate running word count
    wordCounts = words.groupBy("word").count()

    # Start running the query that prints the running counts to the console
    query = wordCounts \
        .writeStream \
        .outputMode("complete") \
        .format("console") \
        .start()

    query.awaitTermination()

2 个答案:

答案 0 :(得分:1)

KafkaUtils类将覆盖"group.id"的参数值。它将从原始组id中连接"spark-executor-"

以下是KafkaUtils的代码:

// driver and executor should be in different consumer groups
    val originalGroupId = kafkaParams.get(ConsumerConfig.GROUP_ID_CONFIG)
    if (null == originalGroupId) {
      logError(s"${ConsumerConfig.GROUP_ID_CONFIG} is null, you should probably set it")
    }
    val groupId = "spark-executor-" + originalGroupId
    logWarning(s"overriding executor ${ConsumerConfig.GROUP_ID_CONFIG} to ${groupId}")
    kafkaParams.put(ConsumerConfig.GROUP_ID_CONFIG, groupId)

我们遇到了同样的问题。 Kafka基于具有预设组ID的ACL,因此唯一的事情是改变kafka配置中的组ID。我们将"spark-executor-" + originalGroupId

放入我们原始群组ID的内部

答案 1 :(得分:1)

现在可以在Spark 3.x中设置group.id。看到Structured Streaming + Kafka Integration Guide的内容:

kafka.group.id :从Kafka读取时在Kafka用户中使用的Kafka组ID。请谨慎使用。默认情况下,每个查询都会生成一个唯一的组ID以读取数据。这样可以确保每个Kafka来源都有自己的使用者组,该使用者组不会受到任何其他使用者的干扰,因此可以读取其订阅主题的所有分区。在某些情况下(例如,基于Kafka组的授权),您可能需要使用特定的授权组ID来读取数据。您可以选择设置组ID。但是,请格外小心,因为这可能会导致意外行为。同时运行的查询(批处理和流处理)或具有相同组ID的源可能会相互干扰,导致每个查询仅读取部分数据。快速连续启动/重新启动查询时,也可能会发生这种情况。为了最大程度地减少此类问题,请将Kafka使用者会话超时(通过设置选项“ kafka.session.timeout.ms”)设置得很小。设置此选项后,选项“ groupIdPrefix”将被忽略。

但是,此group.id仍不用于将偏移提交回Kafka,并且偏移管理仍保留在Spark的检查点文件中。我在答案中提供了更多详细信息(对于Spark <3.x也是如此)