Ste*_*cek 12 scala apache-kafka apache-spark apache-spark-sql spark-structured-streaming
我正在尝试使用基于DataFrame/Dataset API的Spark-Streaming来加载来自Kafka的数据流的结构化流方法.
我用:
Spark Kafka DataSource定义了底层架构:
|key|value|topic|partition|offset|timestamp|timestampType|
Run Code Online (Sandbox Code Playgroud)
我的数据采用json格式,并存储在值列中.我正在寻找一种方法如何从值列中提取底层模式并将接收到的数据帧更新为存储在值中的列?我尝试了下面的方法,但它不起作用:
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()
Run Code Online (Sandbox Code Playgroud)
在这里我得到了Exception,org.apache.spark.sql.AnalysisException: Can't extract value from value#337;因为在创建流时,里面的值是未知的...
你有什么建议吗?
use*_*411 10
从Spark角度来看,value它只是一个字节序列.它不了解序列化格式或内容.为了能够提取字段,您必须先解析它.
如果数据被序列化为JSON字符串,则有两个选项.您可以cast value到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))
Run Code Online (Sandbox Code Playgroud)
或cast向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: _*)
Run Code Online (Sandbox Code Playgroud)
然后cast到所需的类型.
| 归档时间: |
|
| 查看次数: |
5339 次 |
| 最近记录: |