读取卡夫卡主题处理数据,并使用scala和spark写回卡夫卡主题

读取卡夫卡主题处理数据,并使用scala和spark写回卡夫卡主题,scala,apache-spark,apache-kafka,spark-structured-streaming,Scala,Apache Spark,Apache Kafka,Spark Structured Streaming,您好,我正在阅读卡夫卡主题,我想处理从卡夫卡收到的数据,比如tockenization,过滤掉不必要的数据,删除停止词,最后我想写回另一个卡夫卡主题 // read from kafka val readStream = existingSparkSession .readStream .format("kafka") .option("kafka.bootstrap.servers", hostAddress)

您好,我正在阅读卡夫卡主题,我想处理从卡夫卡收到的数据,比如tockenization,过滤掉不必要的数据,删除停止词,最后我想写回另一个卡夫卡主题

// read from kafka
val readStream = existingSparkSession
      .readStream
      .format("kafka")
      .option("kafka.bootstrap.servers", hostAddress)
      .option("subscribe", "my.raw") // Always read from offset 0, for dev/testing purpose
      .load()

val df = readStream.selectExpr("CAST(value AS STRING)" )
df.show(false)
val df_json = df.select(from_json(col("value"), mySchema.defineSchema()).alias("parsed_value"))
val df_text = df_json.withColumn("text", col("parsed_value.payload.Text"))

// perform some data processing actions such as tokenization etc and return cleanedDataframe as the final result

// write back to kafka
val writeStream = cleanedDataframe
      .writeStream
      .outputMode("append")
      .format("kafka")
      .option("kafka.bootstrap.servers", hostAddress)
      .option("topic", "writing.val")
      .start()
    writeStream.awaitTermination()
然后我得到下面的错误

线程“main”org.apache.spark.sql.AnalysisException中的异常: 使用流媒体源的查询必须使用 writeStream.start()

然后,我编辑了我的代码,如下所示,从卡夫卡读取并写入控制台

// read from kafka
val readStream = existingSparkSession
      .readStream
      .format("kafka")
      .option("kafka.bootstrap.servers", hostAddress)
      .option("subscribe", "my.raw") // Always read from offset 0, for dev/testing purpose
      .load()

// write to console
val df = readStream.selectExpr("CAST(value AS STRING)" )
val query = df.writeStream
      .outputMode("append")
      .format("console")
      .start().awaitTermination();

// then perform the data processing part as mentioned in the first half
在第二种方法中,数据连续显示在控制台中,但从未通过数据处理部分运行。我可以知道如何读取卡夫卡主题,然后对接收到的数据执行一些操作(标记化、删除停止词),最后写回新的卡夫卡主题吗

编辑


堆栈跟踪在错误期间指向上述代码中的df.show(false)

当前实现中存在两个常见问题:

  • 在流媒体上下文中应用
    show
  • 等待终止后的代码将不被执行
  • 到1。

    方法
    show
    是对数据帧的操作(与转换相反)。当您处理流式数据帧时,这将导致错误,因为流式查询需要使用
    start
    启动(正如excation文本所告诉您的)

    到2。

    方法
    是一种阻塞方法,这意味着后续代码不会在每个微批中执行

    整体解决方案

    如果您想读取和写入Kafka以及在这两者之间,想通过在控制台中显示数据来了解正在处理的数据,您可以执行以下操作:

    //读卡夫卡
    val readStream=existingSparkSession
    .readStream
    .格式(“卡夫卡”)
    .option(“kafka.bootstrap.servers”,主机地址)
    .option(“subscribe”,“my.raw”)//始终从偏移量0读取,用于开发/测试目的
    .load()
    //写入控制台
    val df=readStream.selectExpr(“转换(值为字符串)”)
    df.writeStream
    .outputMode(“追加”)
    .格式(“控制台”)
    .start()
    val df_json=df.select(从_json(col(“value”),mySchema.defineSchema()).alias(“解析的_值”))
    val df_text=df_json.withColumn(“text”,col(“parsed_value.payload.text”))
    //执行一些数据处理操作,如标记化等,并返回cleanedDataframe作为最终结果
    //回信给卡夫卡
    //数据框“cleanedDataframe”的“key”和“value”列将用于将消息生成到Kafka主题中。
    val writeStreamKafka=cleanedDataframe
    .writeStream
    .outputMode(“追加”)
    .格式(“卡夫卡”)
    .option(“kafka.bootstrap.servers”,主机地址)
    .option(“topic”、“writing.val”)
    .start()
    existingSparkSession.awaitAnyTermination()已存在
    
    注意代码末尾的
    existingSparkSession.awaitAnyTermination()
    ,而不直接在
    启动后使用
    awaitTermination
    。另外,请记住,数据帧
    cleanedDataframe
    key
    value
    列将用于将消息生成到卡夫卡主题中。但是,不需要列
    ,另请参见

    此外,如果使用检查点(推荐),则需要设置两个不同的位置:一个用于控制台流,另一个用于kafka输出流。重要的是要记住,这些流式查询是独立运行的