簡體   English   中英

如何使用Java中的結構化流來從Kafka反序列化記錄?

[英]How to deserialize records from Kafka using Structured Streaming in Java?

我使用Spark 2.1

我試圖使用Spark Structured Streaming從Kafka讀取記錄,反序列化它們並在之后應用聚合。

我有以下代碼:

SparkSession spark = SparkSession
        .builder()
        .appName("Statistics")
        .getOrCreate();

Dataset<Row> df = spark
        .readStream()
        .format("kafka")
        .option("kafka.bootstrap.servers", kafkaUri)
        .option("subscribe", "Statistics")
        .option("startingOffsets", "earliest")
        .load();

df.selectExpr("CAST(value AS STRING)")

我想要的是將value字段反序列化為我的對象而不是像String

我有一個自定義反序列化器。

public StatisticsRecord deserialize(String s, byte[] bytes)

我怎么能用Java做到這一點?


我找到的唯一相關鏈接是這個https://databricks.com/blog/2017/04/26/processing-data-in-apache-kafka-with-structured-streaming-in-apache-spark-2-2 .html ,但這是針對Scala的。

定義JSON消息的模式。

StructType schema = DataTypes.createStructType(new StructField[] { 
                DataTypes.createStructField("Id", DataTypes.IntegerType, false),
                DataTypes.createStructField("Name", DataTypes.StringType, false),
                DataTypes.createStructField("DOB", DataTypes.DateType, false) });

現在閱讀下面的消息。 MessageData是JSON消息的JavaBean。

Dataset<MessageData> df = spark
            .readStream()
            .format("kafka")
            .option("kafka.bootstrap.servers", kafkaUri)
            .option("subscribe", "Statistics")
            .option("startingOffsets", "earliest")
            .load()
            .selectExpr("CAST(value AS STRING) as message")
            .select(functions.from_json(functions.col("message"),schema).as("json"))
            .select("json.*")
            .as(Encoders.bean(MessageData.class));  

如果您的數據庫中有自定義反序列化器,請在load后從Kafka獲取的字節數上使用它。

df.select("value")

該行為您提供只有一個列value Dataset<Row>


我只使用Scala的Spark API,所以我在Scala中執行以下操作來處理“反序列化”案例:

import org.apache.spark.sql.Encoders
implicit val statisticsRecordEncoder = Encoders.product[StatisticsRecord]
val myDeserializerUDF = udf { bytes => deserialize("hello", bytes) }
df.select(myDeserializerUDF($"value") as "value_des")

這應該會給你你想要的......在Scala中。 將它轉換為Java是你的家庭練習:)

請注意,您的自定義對象必須具有可用的編碼器,否則Spark SQL將拒絕將其對象放入數據集中。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM