簡體   English   中英

如何使用 kafka 標頭編寫鑲木地板文件

[英]How to write parquet files with kafka headers

這是我的第一個 Spark 程序。 我想使用 Kafka 消息。 消息包含字節 arr、一些 kafka 標頭和密鑰。所需的輸出是帶有列的鑲木地板文件(kafkaKey、kafkaHeader1、kafkaHeader2、byteArr)。 我試圖用 Spark 來實現它,知道我是如何添加架構的,架構是否正確? 目前我無法控制輸出的外觀?

...
 SparkSession spark = SparkSession
                .builder()
                .appName("Spark Kafka")
                .master("local")
                .getOrCreate();
...

這是創建模式的方法嗎?

        StructType rfSchema = new StructType(new StructField[]{
                new StructField("kafkaHeader1", DataTypes.StringType, false, Metadata.empty()),
                new StructField("kafkaHeader2", DataTypes.StringType, false, Metadata.empty()),
                new StructField("key", DataTypes.LongType, false, Metadata.empty()),
            }
        );


        Dataset<Row> ds = spark
                .readStream()
                .format("kafka")
                .option("kafka.bootstrap.servers", "10.0.0.0:30526")
                .option("subscribe", "test.topic")
                .option("includeHeaders", "true")
                .option("max.poll.records", "4000")
                .option("group.id", "testSpark")
                .option("key.deserializer", "org.apache.kafka.common.serialization.LongDeserializer")
                .option("value.deserializer", "org.apache.kafka.common.serialization.ByteArrayDeserializer")
                .option("startingOffsets", "earliest")
                .option("failOnDataLoss", "false")
                .load();

.. //我在很多例子中都看到了這條線,為什么我需要它? ... ds.selectExpr("CAST(key AS STRING)", "CAST(value AS STRING)", "headers");

        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        String currentDate= format.format(new Date());

        ds.printSchema();
        ds.writeStream()
                .option("checkpointLocation", "/home/xxx/spark3/streamingCheckpoint")
                .format("parquet")
                .outputMode(OutputMode.Append())
                .partitionBy("partition")
                .start("home/xxx/spark3/"+currentDate);
        try {
            Thread.sleep(400000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }

    }
...
Thanks

在很多例子中看到這條線,為什么我需要它?

因為默認情況下,Spark 不會反序列化您的 Kafka 數據。

您需要使用 UDF 函數(例如CAST )來解析value (以及可選的keyheaders

例如,只有在將數據轉換/解析為 Spark StructType之后,您才能寫入結構化格式,例如 Parquet。

順便說一句,Parquet 應該能夠保存數組,所以如果你想要所有的標題而不是只有兩個,請使用ArrayType模式。

話雖如此,從這個開始。

ds.selectExpr("CAST(key AS LONG)", "headers")
    .writeStream

設置deserializer選項無效。

從值的文檔...

始終使用 ByteArrayDeserializer 反序列化為字節數組。 使用 DataFrame 操作顯式反序列化值

並查看“源中的每一行都有以下架構”部分以查看其余數據類型。

暫無
暫無

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

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