在Spark结构化流中从Kafka反序列化Protobuf

时间:2020-03-20 05:23:00

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

我正在测试一个正在实施的实现,每天将收到3亿条消息,并计划进行大规模扩展。此刻似乎有一个步骤看起来很简陋,我很乐意提供一些建议。

我确实用https://scalapb.github.io/sparksql.html刺了一下,但即使按照他们的maven指示,也似乎无法使它起作用。

目前,我有一个protobuf和一个用于同一模型的case类:

message MyThing { // proto
    required string id = 1;
}

case class MyThing(id: String)

然后我有了一个火花readStream

val df =  
  spark.readStream
    .format("kafka")
    // etc
    .load()

kafka有效负载位于“值”列中,该列是已传输的protobuf中的Array [Byte]。我想将该二进制列转换为具有特定StructType的行。

我现在所拥有的使用涉及案例类的奇怪语法:

val encoder = Encoder.product[MyThing]

df
  .select("value")
  .map { row => 
     // from memory so might be slightly off
     val proto = MyThingProto.parseFrom(row.getBinary(0)) 
     val myThing = MyThing.fromProto(proto)
     myThing
  }(encoder)
  .toDF()
  // business logic
  .writeStream
  ...//output

我可以提高效率/更快吗?创建案例类涉及的开销似乎过多。我希望能够执行以下操作:

  .map { row => 
     // from memory so might be slightly off
     val proto = MyThingProto.parseFrom(row.getBinary(0)) 
     val row = buildRow(proto)
     row
  }(encoder??) // what kind of encoder is used here?

  def buildRow(proto: MyThingProto): Row = 
      Row(proto.getId)

这会更好吗?还是使用Kafka解串器接口的UDF?

谢谢。

0 个答案:

没有答案