繁体   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