在使用foreachRDD进行CSV数据处理时出现异常。这是我的代码
case class Person(name: String, age: Long)
val conf = new SparkConf()
conf.setMaster("local[*]")
conf.setAppName("CassandraExample").set("spark.driver.allowMultipleContexts", "true")
val ssc = new StreamingContext(conf, Seconds(10))
val smDstream=ssc.textFileStream("file:///home/sa/testFiles")
smDstream.foreachRDD((rdd,time) => {
val peopleDF = rdd.map(_.split(",")).map(attributes =>
Person(attributes(0), attributes(1).trim.toInt)).toDF()
peopleDF.createOrReplaceTempView("people")
val teenagersDF = spark.sql("insert into table devDB.stam SELECT name, age
FROM people WHERE age BETWEEN 13 AND 29")
//teenagersDF.show
})
ssc.checkpoint("hdfs://go/hive/warehouse/devDB.db")
ssc.start()
我遇到以下错误 java.io.NotSerializableException:已启用DStream检查点,但DStream及其功能不可序列化 org.apache.spark.streaming.StreamingContext 序列化堆栈: -无法序列化的对象(类:org.apache.spark.streaming.StreamingContext,值:org.apache.spark.streaming.StreamingContext@1263422a) -字段(类:$ iw,名称:ssc,类型:类org.apache.spark.streaming.StreamingContext)
请帮助
答案 0 :(得分:0)
这个问题不再有意义了,因为 dStreams已被弃用/放弃。
在代码中需要考虑一些事情,因此很难找到确切的问题。就是说,我不仅要思考,而且我不是序列化专家。
您可以找到一些尝试直接写到Hive表而不是路径的文章,在我的回答中我使用了一种方法,但是您可以使用Spark SQL的方法为TempView编写,这一切都是可能的
我模拟了QueueStream的输入,因此不需要拆分。如果遵循相同的“全局”方法,则可以根据自己的情况对此进行调整。我选择写入需要时创建的镶木地板文件。您可以创建您的tempView,然后按照初始方法使用spark.sql。
DStream的输出操作是:
- print()
- saveAsTextFiles(前缀,[后缀])
- saveAsObjectFiles(前缀,[后缀])
- saveAsHadoopFiles(前缀,[后缀])
- foreachRDD(func)
foreachRDD
最通用的输出运算符,将函数func应用于 从流中生成的每个RDD。此功能应推送数据 在每个RDD中保存到外部系统,例如将RDD保存到文件中,或 通过网络将其写入数据库。注意函数func 在运行流应用程序的驱动程序进程中执行, 并且通常会有RDD动作会迫使 流式RDD的计算。
它说明了保存到文件,但是它可以通过foreachRDD完成您想要的操作,尽管我 认为这个想法是针对外部系统的。保存到文件更快 在我看来,而不是逐步编写表格 直。您希望通过Streaming尽快卸载数据,因为卷通常很高。
两个步骤:
在流类的单独类中-在Spark 2.4下运行:
case class Person(name: String, age: Int)
然后您需要应用流逻辑-您可能需要一些导入 否则我在DataBricks下运行该笔记本时就会发现该笔记本:
import org.apache.spark.sql.SparkSession
import org.apache.spark.rdd.RDD
import org.apache.spark.streaming.{Seconds, StreamingContext}
import scala.collection.mutable
import org.apache.spark.sql.SaveMode
val spark = SparkSession
.builder
.master("local[4]")
.config("spark.driver.cores", 2)
.appName("forEachRDD")
.getOrCreate()
val sc = spark.sparkContext
val ssc = new StreamingContext(spark.sparkContext, Seconds(1))
val rddQueue = new mutable.Queue[RDD[List[(String, Int)]]]()
val QS = ssc.queueStream(rddQueue)
QS.foreachRDD(q => {
if(!q.isEmpty) {
val q_flatMap = q.flatMap{x=>x}
val q_withPerson = q_flatMap.map(field => Person(field._1, field._2))
val df = q_withPerson.toDF()
df.write
.format("parquet")
.mode(SaveMode.Append)
.saveAsTable("SO_Quest_BigD")
}
}
)
ssc.start()
for (c <- List(List(("Fred",53), ("John",22), ("Mary",76)), List(("Bob",54), ("Johnny",92), ("Margaret",15)), List(("Alfred",21), ("Patsy",34), ("Sylvester",7)) )) {
rddQueue += ssc.sparkContext.parallelize(List(c))
}
ssc.awaitTermination()