首页 > 解决方案 > Spark RDD 不变性混淆

问题描述

我目前正在准备我作为数据工程师的工作面试。我陷入了困惑。以下是详细信息。

如果 Spark RDD 本质上是不可变的,那么为什么我们能够使用 var 创建 spark RDD?

标签: scalaapache-sparkrdd

解决方案


您的困惑与 Spark 的 RDD 无关。这将有助于理解变量和对象之间的区别。一个更熟悉的例子:

假设你有一个 String,我们都知道它是一个不可变类型:

var text = "abc"                 //1
var text1 = text                 //2
text = text.substring(0,2)       //3

与 Spark 的 RDD 一样,Strings 是不可变的。但是你认为上面的第 1、2 和 3 行是做什么的?你会说第3行改变了text吗?这就是您的困惑所在:text是一个变量。声明时(第 1 行),text是一个指向"abc"内存中的 String 对象 ( ) 的变量。第 3 行没有修改该"abc"String 对象,但第 3 行创建了一个新String对象 ( "ab"),但重用了相同的变量text来指向它。为了加强这一点,请注意texttext1是指向同一个对象的两个不同变量(与"abc"第 1 行创建的相同)

如果你看到一个变量和它可能指向的对象是两个不同的东西,很容易将它应用到你的 RDD 示例中(实际上它与上面的 String 示例非常相似):

var a = sc.parallelize(Seq("1", "2", "3")) //like line 1 above
a = a.map(_ + " is a number")              //like line 3 above 

因此,第一行在内存中创建了一个 RDD 对象,然后声明了一个变量a,然后a指向该 RDD 对象。第二行计算一个新的 RDD 对象(关闭第一个),但重用相同的变量。

这意味着从第一个 RDD 对象a.map(_ + " is a number")创建一个的RDD 对象(并且第一个不再分配给变量,因为您重用了相同的变量来指向派生的 RDD)。

简而言之:当我们说 Spark 的 RDD 是不可变的时,我们的意思是那些对象(不是指向它们的变量)不能被变异(不能修改对象在内存中的结构),即使指向它们的非最终变量可以重新分配,就像 String 对象一样。

这是关于编程基础的,我建议您在这篇文章中进行一些类比:变量、对象和引用之间有什么区别?


推荐阅读