Как читать записи в формате JSON из Kafka с помощью структурированной потоковой передачи?
Я пытаюсь использовать структурированный потоковый подход использование Spark-Streaming на основе API DataFrame / Dataset для загрузки потока данных из Kafka.
Я использую:
- Искра 2.10
- Кафка 0.10
- Искра-sql-Кафка-0-10
источник данных Spark Kafka определил базовую схему:
|key|value|topic|partition|offset|timestamp|timestampType|
мои данные приходят в формате JSON, и они хранятся в стоимостью. Я поиск способа извлечения базовой схемы из столбца value и обновления полученного фрейма данных до Столбцов, хранящихся в стоимостью? Я попробовал подход ниже, но он не работает:
val columns = Array("column1", "column2") // column names
val rawKafkaDF = sparkSession.sqlContext.readStream
.format("kafka")
.option("kafka.bootstrap.servers","localhost:9092")
.option("subscribe",topic)
.load()
val columnsToSelect = columns.map( x => new Column("value." + x))
val kafkaDF = rawKafkaDF.select(columnsToSelect:_*)
// some analytics using stream dataframe kafkaDF
val query = kafkaDF.writeStream.format("console").start()
query.awaitTermination()
здесь я получаю исключение org.apache.spark.sql.AnalysisException: Can't extract value from value#337;
потому что во время создания потока значения внутри не известны...
у вас есть какие-либо предложения?
1 ответов
С точки зрения искры value
- это просто последовательность байтов. Он не имеет знаний о формате сериализации или содержимом. Чтобы иметь возможность извлечь файл, вы должны сначала проанализировать его.
если данные сериализуются как строка JSON, у вас есть два варианта. Ты можешь!--3--> value
to StringType
и использовать from_json
и предоставить схему:
import org.apache.spark.sql.types._
import org.apache.spark.sql.functions.from_json
val schema: StructType = StructType(Seq(
StructField("column1", ???),
StructField("column2", ???)
))
rawKafkaDF.select(from_json($"value".cast(StringType), schema))
или cast
to StringType
, извлекать поля по пути с помощью get_json_object
:
import org.apache.spark.sql.functions.get_json_object
val columns: Seq[String] = ???
val exprs = columns.map(c => get_json_object($"value", s"$$.$c"))
rawKafkaDF.select(exprs: _*)
и cast
позже желаемый тип.