Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala foreachPartitionAsync抛出无法在已停止的SparkContext上调用方法_Scala_Asynchronous_Apache Spark_Future - Fatal编程技术网

Scala foreachPartitionAsync抛出无法在已停止的SparkContext上调用方法

Scala foreachPartitionAsync抛出无法在已停止的SparkContext上调用方法,scala,asynchronous,apache-spark,future,Scala,Asynchronous,Apache Spark,Future,我有两个不同数据的文件。我试图在2个不同的RDD中读取它们,然后将它们转换为数据帧并插入到hive中。我能够完成这个普通的代码,但是spark处理了一个又一个RDD计算。所以第二个在等待第一个过去,尽管我在集群中有足够的资源。我了解到RDDs计算可以使用异步方法并行化。所以我正在尝试foreachPartitionAsync。但它抛出了我无法进一步调试的错误。示例代码: object asynccode { def main(args: Array[String]) = { val

我有两个不同数据的文件。我试图在2个不同的RDD中读取它们,然后将它们转换为数据帧并插入到hive中。我能够完成这个普通的代码,但是spark处理了一个又一个RDD计算。所以第二个在等待第一个过去,尽管我在集群中有足够的资源。我了解到RDDs计算可以使用异步方法并行化。所以我正在尝试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)

我错过了什么吗?

您停止
SparkContext
,而不必等待
未来行动的完成。您应该等待操作完成并停止上下文响应:

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
}
也就是说,即使我们忽略异步操作,您的代码也是无效的。不能在操作或转换中使用分布式数据结构

如果您想要异步写入操作,请直接使用
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"))
并等待上述操作完成

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"))