Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/apache-spark/5.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
Apache spark 如何在结构化流媒体中正确使用foreachBatch.batchDF.unpersist()?(有个错误)_Apache Spark_Caching_Compiler Errors_Spark Structured Streaming - Fatal编程技术网

Apache spark 如何在结构化流媒体中正确使用foreachBatch.batchDF.unpersist()?(有个错误)

Apache spark 如何在结构化流媒体中正确使用foreachBatch.batchDF.unpersist()?(有个错误),apache-spark,caching,compiler-errors,spark-structured-streaming,Apache Spark,Caching,Compiler Errors,Spark Structured Streaming,我正在使用Spark 3.0的结构化流媒体 我要做的是将数据写入多个接收器。我需要在Kafka中编写一些数据帧,以便在另一个进程中使用,还需要在Cassandra中存储相同的数据帧,以供以后使用(一些仪表板等) 对于目标过程,我编写了如下代码。我参考了来自中国的官方文件 但是,每当我在foreachBatch的最后一部分中写入batchDF.unpersist()时,就会出现编译错误: [error] (function: org.apache.spark.api.java.function

我正在使用Spark 3.0的结构化流媒体

我要做的是将数据写入多个接收器。我需要在Kafka中编写一些数据帧,以便在另一个进程中使用,还需要在Cassandra中存储相同的数据帧,以供以后使用(一些仪表板等)

对于目标过程,我编写了如下代码。我参考了来自中国的官方文件

但是,每当我在foreachBatch的最后一部分中写入
batchDF.unpersist()
时,就会出现编译错误:

[error]   (function: org.apache.spark.api.java.function.VoidFunction2[org.apache.spark.sql.Dataset[org.apache.spark.sql.Row],java.lang.Long])org.apache.spark.sql.streaming.DataStreamWriter[org.apache.spark.sql.Row] <and>
[error]   (function: (org.apache.spark.sql.Dataset[org.apache.spark.sql.Row], scala.Long) => Unit)org.apache.spark.sql.streaming.DataStreamWriter[org.apache.spark.sql.Row]
[error]  cannot be applied to ((org.apache.spark.sql.DataFrame, scala.Long) => org.apache.spark.sql.DataFrame)
[error]       .foreachBatch({(batchDF: DataFrame, batchId: Long) => {
[error]        ^
[error] one error found
[error] (Compile / compileIncremental) Compilation failed
[error](函数:org.apache.spark.api.java.function.VoidFunction2[org.apache.spark.sql.Dataset[org.apache.spark.sql.Row],java.lang.Long])org.apache.spark.sql.streamwriter[org.apache.spark.sql.Row]
[错误](函数:(org.apache.spark.sql.Dataset[org.apache.spark.sql.Row],scala.Long)=>Unit)org.apache.spark.sql.streaming.DataStreamWriter[org.apache.spark.sql.Row]
[错误]无法应用于((org.apache.spark.sql.DataFrame,scala.Long)=>org.apache.spark.sql.DataFrame)
[错误].foreachBatch({(batchDF:DataFrame,batchId:Long)=>{
[错误]^
[错误]发现一个错误
[错误](编译/编译增量)编译失败
当我删除
batchDF.unpersist()
时,它工作正常,并且我检查了数据是否能很好地进入Kafka和Cassandra。但是,很明显,它很快就出现了内存不足错误,因为缓存的数据仍保留在内存中

我还尝试使用
sparkSession.catalog.clearCache()
,但它似乎没有按我的预期工作

为什么会发生此错误,因为我的代码与文档完全相同?另外,如何修复它


提前感谢。

Spark为Scala和Java提供了两种不同的方法,因为Scala在Scala 2.12之前不生成Java lambda

  /**
   * Applies a function `f` to all rows.
   *
   * @group action
   * @since 1.6.0
   */
  def foreach(f: T => Unit): Unit = withNewRDDExecutionId {
    rdd.foreach(f)
  }

  /**
   * (Java-specific)
   * Runs `func` on each element of this Dataset.
   *
   * @group action
   * @since 1.6.0
   */
  def foreach(func: ForeachFunction[T]): Unit = foreach(func.call(_))
这是为了方便Java用户,但一旦Spark开始支持Scala 2.12,这些方法就会相互冲突


Spark社区中进行了相关讨论,但似乎做出了保持API兼容性的决定。不幸的是,您需要“严格”匹配两个方法之间的签名之一,例如,在lambda的末尾添加
Unit

根据错误消息和几次实验猜测,我确认当
foreachBatch
中的函数以
batchDF.unpersist()结尾时,代码出现编译错误
。所以我只是在函数末尾使用无意义的逻辑来避免编译错误(例如
if(false){}
),但我仍然不知道为什么会发生这种情况..这是scala问题,因为方法中的最后一行是该方法的返回值。因此编译的签名与预期的签名不匹配。尝试将
foreachBatch
中的所有函数代码提取到一个声明返回
Unit
的方法中,然后这会解决你的问题。
  /**
   * Applies a function `f` to all rows.
   *
   * @group action
   * @since 1.6.0
   */
  def foreach(f: T => Unit): Unit = withNewRDDExecutionId {
    rdd.foreach(f)
  }

  /**
   * (Java-specific)
   * Runs `func` on each element of this Dataset.
   *
   * @group action
   * @since 1.6.0
   */
  def foreach(func: ForeachFunction[T]): Unit = foreach(func.call(_))