如何通过Java Spark结构化流从Kafka主题中正确使用

时间:2019-07-04 11:58:54

标签: java apache-spark apache-kafka protocol-buffers spark-structured-streaming

我是kafka-spark流媒体的新手,并尝试使用协议缓冲区序列化器/解串器来实现spark文档中的示例。到目前为止,我遵循

上的官方教程

https://spark.apache.org/docs/2.2.0/structured-streaming-kafka-integration.html https://developers.google.com/protocol-buffers/docs/javatutorial

现在我继续解决以下问题。这个问题可能与这篇文章How to deserialize records from Kafka using Structured Streaming in Java?

类似

我已经成功实现了序列化程序,该序列化程序将消息写入kafka主题。现在的任务是使用自定义解串器通过Spark结构化流来使用它。

public class CustomDeserializer implements Deserializer<Person> {

@Override
public Person deserialize(String topic, byte[] data) {
    Person person = null;
    try {
        person = Person.parseFrom(data);

        return person;
    } catch (Exception e) {
               //ToDo
    }

    return null;
 }


Dataset<Row> dataset = sparkSession.readStream()
        .format("kafka")
        .option("kafka.bootstrap.servers", "localhost:9092")
        .option("subscribe", topic)
        .option("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer")
        .option("value.deserializer", "de.myproject.CustomDeserializer")
        .load()
        .select("value");

    dataset.writeStream()
        .format("console")
        .start()
        .awaitTermination();

但是作为输出,我仍然得到二进制文件。

-------------------------------------------
Batch: 0
-------------------------------------------
+--------------------+
|               value|
+--------------------+
|[08 AC BD BB 09 1...|
+--------------------+

-------------------------------------------
Batch: 1
-------------------------------------------
+--------------------+
|               value|
+--------------------+
|[08 82 EF D8 08 1...|
+--------------------+

关于本教程,我只需要将value.deserializer的选项设置为具有人类可读格式

.option("value.deserializer", "de.myproject.CustomDeserializer")

我错过了什么吗?

2 个答案:

答案 0 :(得分:0)

您是否错过了文档的这一部分?

  

请注意,无法设置以下Kafka参数,并且Kafka源或接收器将引发异常:

     
      
  • key.deserializer :始终使用ByteArrayDeserializer将键反序列化为字节数组。使用DataFrame操作显式反序列化键。
  •   
  • value.deserializer :始终使用ByteArrayDeserializer将值反序列化为字节数组。使用DataFrame操作显式反序列化值。
  •   

您必须注册一个调用解串器的UDF

类似于Read protobuf kafka message using spark structured streaming

答案 1 :(得分:0)

您需要将字节转换为 String 数据类型。 Dataset.selectExpr(“ CAST(key AS STRING)”,“ CAST(value AS STRING)”)

然后,您可以使用函数。 from_json (dataset.col(“ value”),StructType)以获取实际的DF。

快乐编码:)