我有2个不同数据的文件。我试图在2差分RDD&读取它们然后将它们转换为Dataframe&插入蜂巢。我能够做这个正常的代码。但是火花处理了一个接一个的RDD计算。因此,虽然我在群集中有足够的资源,但第二个人正在等待第一个人过来。我了解到可以使用异步方法并行化RDD计算。所以我正在尝试foreachPartitionAsync。但它会抛出错误,我无法进一步调试。示例代码:
object asynccode {
def main(args: Array[String]) = {
val conf = new SparkConf()
.setAppName("Parser")
val sc = new SparkContext(conf)
val hiveContext = new HiveContext(sc)
import hiveContext.implicits._
val ercs = sc.wholeTextFiles("hdfs://x.x.x.x:8020/file1.txt")
val test = ercs.map { k =>
var rc = method1(k._2, k._1).toSeq
rc
}
.flatMap(identity)
.foreachPartitionAsync { f =>
f.toSeq.toDF()
.write.insertInto("dbname.tablename1")
}
val ercs2 = sc.wholeTextFiles("hdfs://x.x.x.x:8020/file2.txt")
val test2 = ercs2.map { k =>
var rs = method2(k._2, k._1)
rs
}
.flatMap(identity)
.foreachPartitionAsync(f => f.toSeq.toDF()
.write.insertInto("dbname.tablename2")
)
sc.stop()
}
def method1 = ???
def method2 = ???
}
但它会抛出以下错误消息。如果我从代码中删除foreachPartitionAsync,它可以正常工作。不确定我对foreachPartitionAsync做错了什么。
任务序列化失败:java.lang.IllegalStateException:无法在已停止的SparkContext上调用方法。
更新: 谢谢你的建议。我在下面更新了它。但现在它根本没有做任何事情。 Spark web UI,我可以看到没有触发任何阶段(它是空的)。我的所有表都没有更新。但是工作完成没有错误。
val ercs = sc.wholeTextFiles("hdfs://x.x.x.x:8020/file1.txt")
val test = ercs.map { k =>
var rc = method1(k._2, k._1).toSeq
rc
}
.flatMap(identity)
toDF()
val f1 = Future(test.write.insertInto("dbname.tablename1"))
}
val ercs2 = sc.wholeTextFiles("hdfs://x.x.x.x:8020/file2.txt")
val test2 = ercs2.map { k =>
var rs = method2(k._2, k._1)
rs
}
.flatMap(identity)
toSeq.toDF()
val f2 = Future(test2.write.insertInto("dbname.tablename2"))
)
Future.sequence(Seq(f1,f2)).onComplete(_ => sc.stop)
我错过了什么?
答案 0 :(得分:1)
您无需等待SparkContext
完成就停止FutureActions
。您应该等待操作完成并停止响应中的上下文:
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.Future
import scala.util.{Success, Failure}
val f1: Future[Unit] = sc.range(1, 200).foreachAsync(_ => Thread.sleep(10))
val f2: Future[Unit] = sc.range(1, 200).foreachAsync(_ => Thread.sleep(10))
Future.sequence(Seq(f1, f2)).onComplete {
case Success(_) => sc.stop
case Failure(e) =>
e.printStackTrace // or some other appropriate actions
sc.stop
}
即使我们忽略了异步操作,也说你的代码无效。您无法在操作或转换中使用分布式数据结构:
.foreachPartitionAsync(
f => f.toSeq.toDF().write.insertInto("dbname.tablename2")
)
如果您想要异步写入操作,请直接使用Futures
:
val df1: Dataframe = ???
val df2: Dataframe = ???
val f1: Future[Unit] = Future(df1.write.insertInto("dbname.tablename1"))
val f2: Future[Unit] = Future(df2.write.insertInto("dbname.tablename2"))
并等待操作完成,如上所示。