I'm writing a Spark application that uses structured streaming. The app reads messages from a Kafka topic topic1, constructs a new message, serializes it to an Array[Byte] and publishes them to another Kafka topic topic2.
The serializing to a byte array is important because I use a specific serializer/deserializer that the downstream consumer of topic2 also uses.
I've trouble producing to Kafka though. I'm not even sure how to do so..there's only plenty of examples online about queueing JSON data.
The code -
case class OutputMessage(id: String, bytes: Array[Byte])
implicit val encoder: Encoder[OutputMessage] = org.apache.spark.sql.Encoders.kryo
val outputMessagesDataSet: DataSet[OutputMessage] = spark.readStream
.format("kafka")
.option("kafka.bootstrap.servers", "server1")
.option("subscribe", "topic1")
.load()
.select($"value")
.mapPartitions{r =>
val messages: Iterator[OutputMessage] = createMessages(r)
messages
}
outputMessagesDataSet
.writeStream
.selectExpr("CAST(id AS String) AS key", "bytes AS value")
.format("kafka")
.option("kafka.bootstrap.servers", "server1")
.option("topic", "topic2")
.option("checkpointLocation", loc)
.trigger(trigger)
.start
.awaitTermination
However, that throws exception org.apache.spark.sql.AnalysisException: cannot resolve 'id' given input columns: [value]; line 1 pos 5;
How do I queue to Kafka with id as the key and bytes as the value?