繁体   English   中英

Spark Dataframe以avro格式写入kafka主题?

[英]Spark Dataframe write to kafka topic in avro format?

我在Spark中有一个看起来像的Dataframe

eventDF

   Sno|UserID|TypeExp
    1|JAS123|MOVIE
    2|ASP123|GAMES
    3|JAS123|CLOTHING
    4|DPS123|MOVIE
    5|DPS123|CLOTHING
    6|ASP123|MEDICAL
    7|JAS123|OTH
    8|POQ133|MEDICAL
    .......
    10000|DPS123|OTH

我需要以Avro格式将其写入Kafka主题,目前我可以使用以下代码在Kafka中编写JSON

val kafkaUserDF: DataFrame = eventDF.select(to_json(struct(eventDF.columns.map(column):_*)).alias("value"))
  kafkaUserDF.selectExpr("CAST(value AS STRING)").write.format("kafka")
    .option("kafka.bootstrap.servers", "Host:port")
    .option("topic", "eventdf")
    .save()

现在我想以Avro格式将其写入Kafka主题

Spark> = 2.4

您可以使用to_avro从功能spark-avro库。

import org.apache.spark.sql.avro._

eventDF.select(
  to_avro(struct(eventDF.columns.map(column):_*)).alias("value")
)

Spark <2.4

你必须以同样的方式做到这一点:

  • 创建一个函数,将序列化的Avro记录写入ByteArrayOutputStream并返回结果。 一个天真的实现(这只支持平面对象)可能类似于(由Sushil Kumar SinghKafka Avro Scala示例中采用)

     import org.apache.spark.sql.Row def encode(schema: org.apache.avro.Schema)(row: Row): Array[Byte] = { val gr: GenericRecord = new GenericData.Record(schema) row.schema.fieldNames.foreach(name => gr.put(name, row.getAs(name))) val writer = new SpecificDatumWriter[GenericRecord](schema) val out = new ByteArrayOutputStream() val encoder: BinaryEncoder = EncoderFactory.get().binaryEncoder(out, null) writer.write(gr, encoder) encoder.flush() out.close() out.toByteArray() } 
  • 将其转换为udf

     import org.apache.spark.sql.functions.udf val schema: org.apache.avro.Schema val encodeUDF = udf(encode(schema) _) 
  • 使用它作为替换to_json替代to_json

     eventDF.select( encodeUDF(struct(eventDF.columns.map(column):_*)).alias("value") ) 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM