【问题标题】:Spark RDD immutability ConfusionSpark RDD 不变性混淆
【发布时间】:2020-12-18 16:14:15
【问题描述】:

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

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

【问题讨论】:

  • RDD 是不可变的(这意味着您不能更改 RDD 的状态(即您不能在 RDD 中添加新记录或删除记录或更新记录。) .....“var” 只是持有“任何变量”的引用......如果你改变对不同对象的引用并不意味着你改变了 rdd 的状态,这意味着你改变了引用变量的状态。
  • 如果是这种情况,那么假设我做了 var a= sc.parallelize(Seq("1","2","3")) ,然后如果我做了 a=a.map (_+" 是一个数字")。那么在这种情况下,如果我为 a 执行 foreach(println) 那么最新更改的 rdd 将会出现。但接下来我们将如何获取应用 map 函数之前的早期代码。 @kavetiraviteja

标签: scala apache-spark rdd


【解决方案1】:

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

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

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")。 "abc" String 对象并没有被第 3 行修改,但是第 3 行创建了一个新的String 对象("ab"),但重用了相同的变量text 来指向它。为了加强这一点,请注意 texttext1 是指向同一个对象的两个不同变量(由第 1 行创建的同一个 "abc"

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

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 对象(与第一行不同),但重用了相同的变量。

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

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

这是关于编程基础的,我建议你在这篇文章中进行一些类比:What is the difference between a variable, object, and reference?

【讨论】:

  • 好吧,我同意你的看法,但如果是这样,那么假设我做了 var a= sc.parallelize(Seq("1","2","3")) ,然后如果我a=a.map(_+" is a number").那么在这种情况下,如果我为 a 执行 foreach(println) 那么最新更改的 rdd 将会出现。但接下来我们将如何获取应用 map 函数之前的早期代码。
  • 不确定这与您之前的示例有何不同,我在这个答案中提到了这个示例。如果您执行a = a.map(_+" is a number"),那么您使用var a= sc.parallelize(Seq("1","2","3")) 创建的第一个RDD 将无法再直接访问,因为您使用派生的RDD 覆盖了变量。如果您想同时访问原始 RDD 和派生 RDD,则必须使用两个变量,例如 var b = a.map(_+" is a number")
  • @Noob_developer 你的例子和var a = sc.parallelize(Seq("1","2","3")).map(_+" is a number") 一样。创建了两个RDD,但最后只分配了最后一个给a
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-04-03
  • 1970-01-01
  • 1970-01-01
  • 2011-07-03
  • 2011-01-11
  • 1970-01-01
  • 2016-01-14
相关资源
最近更新 更多