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
Scala rdd与数据帧Spark上的序列化_Scala_Apache Spark_Serialization_Closures - Fatal编程技术网

Scala rdd与数据帧Spark上的序列化

Scala rdd与数据帧Spark上的序列化,scala,apache-spark,serialization,closures,Scala,Apache Spark,Serialization,Closures,EX1。这与RDD一起提供了我们所期望的序列化,无论有无对象,val num都是罪魁祸首,很好: object Example { val r = 1 to 1000000 toList val rdd = sc.parallelize(r,3) val num = 1 val rdd2 = rdd.map(_ + num) rdd2.collect } Example EX2。然而,以类似的方式使用数据帧并不能解决这个问题。为什么看起来是一样的?我错过了什么 object Ex

EX1。这与RDD一起提供了我们所期望的序列化,无论有无对象,val num都是罪魁祸首,很好:

object Example {
 val r = 1 to 1000000 toList
 val rdd = sc.parallelize(r,3)
 val num = 1
 val rdd2 = rdd.map(_ + num)
 rdd2.collect  
}
Example
EX2。然而,以类似的方式使用数据帧并不能解决这个问题。为什么看起来是一样的?我错过了什么

object Example {
import spark.implicits._
import org.apache.spark.sql.functions._

val n = 1 
val df = sc.parallelize(Seq(
    ("r1", 1, 1),
    ("r2", 6, 4),
    ("r3", 4, 1),
    ("r4", 1, 2)
    )).toDF("ID", "a", "b")
df.repartition(3).withColumn("plus1", $"b" + n).show(false)
}
Example
我对DF不完全清楚的原因,也会期望类似的行为。看起来DSs绕过了一些问题,但我可能遗漏了一些东西


在Databricks上运行会产生大量序列化问题,所以不要认为这会影响事情,测试起来很方便

原因很简单,而且比
RDD
Dataset
之间的区别更为根本:

  • 第一段代码对函数求值

    _ + num
    
    因此,必须对其进行计算和评估

  • 第二段代码没有。跟随

    $"b" + n
    
    只是一个值,因此不需要闭包计算和后续序列化

如果仍然不清楚,您可以这样考虑:

  • 前一段代码告诉Spark如何做某事
  • 后一段代码告诉Spark该做什么。实际执行的代码是在不同的范围内生成的
如果您的
数据集
代码更接近它的
RDD
对应项,例如:

object Example {
  import spark.implicits._

  val num = 1
  spark.range(1000).map(_ + num).collect
} 


它会因序列化异常而失败,这与
RDD
版本一样。

原因很简单,而且比
RDD
Dataset
之间的区别更为根本:

  • 第一段代码对函数求值

    _ + num
    
    因此,必须对其进行计算和评估

  • 第二段代码没有。跟随

    $"b" + n
    
    只是一个值,因此不需要闭包计算和后续序列化

如果仍然不清楚,您可以这样考虑:

  • 前一段代码告诉Spark如何做某事
  • 后一段代码告诉Spark该做什么。实际执行的代码是在不同的范围内生成的
如果您的
数据集
代码更接近它的
RDD
对应项,例如:

object Example {
  import spark.implicits._

  val num = 1
  spark.range(1000).map(_ + num).collect
} 


它将因序列化异常而失败,这与
RDD
版本相同。

在您的示例中,将
n
更改为
lit(n)
,应该可以。第一个参数是一列,因此第二个参数应该是一列。如果你使用标量值,你应该告诉spark,否则,它会试图找到变量(
n
),并期望它是
类型,这在你的例子中是不正确的n很好,r这是重点,但我明白了,只是想非常精确地将
n
更改为
lit(n)
,应该没问题。第一个参数是一列,因此第二个参数应该是一列。如果你使用标量值,你应该告诉spark,否则,它会试图找到变量(
n
),并期望它是
类型,这在你的情况下是不正确的n工作很好,r这是重点,但我明白了,只是想非常精确