具有结构化流协议的Apache Kafka

时间:2019-09-24 00:42:10

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

我正在尝试使用结构化流来编写(protobuf的)Kafka使用者。我们称protobuf为A,它应该在Scala中反序列化为字节数组(Array [Byte])。

我尝试了所有可以在网上找到的方法,但仍然不知道如何正确解析消息A

方法1:从集成指南(https://spark.apache.org/docs/2.2.0/structured-streaming-kafka-integration.html)中,我应该将value强制转换为String。但是,即使我执行getBytes将字符串转换为字节以便解析消息A,我也会得到:

Exception in thread "main" java.lang.ExceptionInInitializerError
...
Caused by: com.fasterxml.jackson.databind.JsonMappingException: Incompatible Jackson version: 2.9.8

方法2:我想将值直接转换为字节数组。我会得到:

missing ')' at '['(line 1, pos 17)

== SQL ==
CAST(key AS Array[Byte])

方法3:我遵循(https://databricks.com/blog/2017/04/26/processing-data-in-apache-kafka-with-structured-streaming-in-apache-spark-2-2.html)编写了自己的protobuf反序列化器。但是收到错误消息:

Schema for type A is not supported

以上三种方法可能是我可以在网上找到的所有方法。这应该是一个简单而常见的问题,因此,如果有人对此有所了解,请告诉我。

谢谢!

1 个答案:

答案 0 :(得分:0)

从流源创建的DataFrame的架构为:

root
 |-- key: binary (nullable = true)
 |-- value: binary (nullable = true)
 |-- topic: string (nullable = true)
 |-- partition: integer (nullable = true)
 |-- offset: long (nullable = true)
 |-- timestamp: timestamp (nullable = true)
 |-- timestampType: integer (nullable = true)

因此键和值实际上在Array[Byte]中。您将必须在Dataframe操作中执行反序列化。

例如,我有这个用于Kafka反序列化:

  import sparkSession.implicits._

  sparkSession.readStream
    .format("kafka")
    .option("subscribe", topic)
    .option(
      "kafka.bootstrap.servers",
      bootstrapServers
    )
    .load()
    .selectExpr("key", "value") // Selecting only key & value
    .as[(Array[Byte], Array[Byte])]
    .flatMap {
      case (key, value) =>
        for {
          deserializedKey <- Try {
            keyDeserializer.deserialize(topic, key)
          }.toOption
          deserializedValue <- Try {
            valueDeserializer.deserialize(topic, value)
          }.toOption
        } yield (deserializedKey, deserializedValue)
    }

您需要对其进行修改以反序列化您的protobuf记录。