这里的目标如下:
每隔N秒使用Spark Streaming从Socket读取数据
将收到的数据注册为SQL表
将从HDFS等读取更多数据作为参考数据,它们也将被注册为SQL表
这个想法是对组合的流媒体和放大器执行任意SQL查询。参考数据
请参阅下面的代码段。我看到数据从"内部"写入磁盘。写入forEachRDD循环时,相同的已注册SQL表的数据为空时#34;外部" forEachRDD循环。
请提出您的意见/建议以解决此问题。还有任何其他机制来实现上述"目标"很受欢迎。
case class Record(id:Int, status:String, source:String)
object SqlApp2 {
def main(args: Array[String]) {
val sparkConf = new SparkConf().setAppName("SqlApp2").setMaster("local[2]")
val sc = new SparkContext(sparkConf)
val sqlContext = new SQLContext(sc)
// Create the streaming context with a 10 second batch size
val ssc = new StreamingContext(sc, Seconds(10))
val lines = ssc.socketTextStream("localhost", 9999, StorageLevel.MEMORY_AND_DISK_SER)
var alldata:DataFrame=sqlContext.emptyDataFrame
alldata.registerTempTable("alldata")
lines.foreachRDD((rdd: RDD[String], time: Time) => {
import sqlContext.implicits._
// Convert RDD[String] to DataFrame
val data = rdd.map(w => {
val words = w.split(" ")
Record(words(0).toInt, words(1), words(2))}).toDF()
// Register as table
data.registerTempTable("alldata")
data.save("inside/file"+System.currentTimeMillis(), "json", SaveMode.ErrorIfExists) // this data is written properly
})
val dataOutside = sqlContext.sql("select * from alldata")
dataOutside.save("outside/file"+System.currentTimeMillis(), "json", SaveMode.ErrorIfExists) // this data is empty, how to make the SQL table registered inside the forEachRDD loop visible for rest of application
ssc.start()
ssc.awaitTermination()
}
谢谢&此致
MK
答案 0 :(得分:0)
我的理解是你可以只在'foreachRDD'之类的块中创建create表,除非你去Structured Streaming route。使用您的方法,您可以使用滑动窗口在表中保留一定数量的数据。我在下面给出了相关代码。
// You could create a window of 1 minute to run your query
val windowedStream = lines.window(Seconds(60))
windowedStream.foreachRDD((rdd: RDD[String], time: Time) => {
import sqlContext.implicits._
val data = rdd.map(w => {
val words = w.split(" ")
Record(words(0).toInt, words(1), words(2))
}).toDF()
data.createOrReplaceTempView("alldata")
// You can read your other data source and convert it into a DF table
// and join with the 'alldata' table
val dataInside = sqlContext.sql("select * from alldata")
dataInside.show()
})
希望这会有所帮助。
请注意,Structured Streaming处于初始阶段,功能非常有限。