如何使用具有不同架构的spark readStream()
从多个主题阅读,以及如何使用Spark writeStream()
从StructedSchema
阅读单个主题。
注意:每个输入主题都有不同的模式
答案 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))
然后您可以根据需要写信以分隔主题。