阅读多个主题并写入单个主题-Spark Streaming

时间:2019-06-12 13:02:10

标签: scala apache-spark apache-kafka

如何使用具有不同架构的spark readStream()从多个主题阅读,以及如何使用Spark writeStream()StructedSchema阅读单个主题。

注意:每个输入主题都有不同的模式

1 个答案:

答案 0 :(得分:1)

  

如何使用spark readStream()从多个主题中进行读取,   不同的模式,并使用Spark将writeStream()写入单个主题   StructedSchema?

我在这里给出一般性想法或指示....可能适合您的情况。

我假设您使用的是Avro消息,有2个主题,一个是消息,另一个是我要引用的架构,即消息主题和架构主题。

现在,准备一个通用的行包装器架构,例如avro_yourrow_wrapper.avsc,其中包含不同的架构消息(因为您告诉每个消息都有不同的架构)。例如... 根据您的要求修改此示例。

{
  "type" : "record",
  "name" : "generic_schema",
  "namespace" : "yournamespace",
  "fields" : [ {
    "name" : "messagenameOrTableNames",
    "type" : "string"
  }, {
    "name" : "schema",
    "type" : "long"
  }, {
    "name" : "payload",
    "type" : "bytes"
  } ]
}

将其保存到文件avro_yourrow_wrapper.avsc,因为它是静态的...

// Read the wrapper schema in your consumer.
    val inputStream = getClass.getResourceAsStream("avro_yourrow_wrapper.avsc")
    val source = scala.io.Source.fromInputStream(inputStream)
    val wrapperSchema = try source.mkString finally source.close()
从Spark结构化流中,您将获得一个数据框。根据消息类型读取包装器模式,通过读取模式主题和消息主题读取avro消息,应用记录特定的模式。

现在,使用twitter bijection api(带有GenericRecord),您可以将消息解码为可读格式。

样本伪代码段:

import com.twitter.bijection.Injection
        import com.twitter.bijection.avro.GenericAvroCodecs
        import org.apache.avro.generic.GenericRecord
        val schema = new Schema.Parser().parse(localschema.get( recordlevelschema).get)
        val recordInjection: Injection[GenericRecord, Array[Byte]] = GenericAvroCodecs.toBinary(schema)
        val record: GenericRecord = recordInjection.invert(bytes).get
        log.info("record.getSchema" +record.getSchema)
        record.getSchema.getFields.toArray().foreach(x =>log.info(x.toString))

然后您可以根据需要写信以分隔主题。