Spark RDD不可变性困惑:为何可用var声明Spark RDD?
关于Spark RDD不可变性与var声明的困惑解答
嘿,这个问题其实是把变量的可变性和RDD本身的不可变性搞混啦,我当初刚学Spark的时候也踩过这个坑😅
咱们拆开来说清楚:
1. RDD的不可变性到底指什么?
RDD的不可变性是指一旦创建完成,这个RDD对象本身的数据集、依赖关系、分区信息就再也不能被修改。你没法直接往已有的RDD里追加数据、删除元素,或者更改它的分区规则——任何针对RDD的变换操作(比如map、filter、reduceByKey)都会生成一个全新的RDD实例,原来的RDD会原封不动地保留下来。
2. var声明的是“指向RDD的变量”,不是RDD本身
用var关键字声明的是一个变量引用,它的作用是指向某个RDD对象。这个变量本身是可以被重新赋值的——也就是说,你可以让它从指向A RDD,改成指向B RDD,但这完全不会改变A或B RDD本身的不可变性。
举个实际的代码例子:
// 初始化变量rdd,指向第一个RDD(包含1,2,3) var rdd = sc.parallelize(Seq(1,2,3)) // 执行map操作生成新的RDD(包含2,4,6),然后让rdd变量指向这个新RDD rdd = rdd.map(_ * 2)
这里的操作并没有修改最初那个包含1,2,3的RDD,它依然存在于Spark的计算图里,只是我们的rdd变量不再指向它了而已。
3. 对比val的情况更清晰
如果用val声明变量,这个变量引用就不能被重新赋值,但这和RDD的不可变性依然是两回事:
// val变量rdd指向初始RDD,不能再被重新赋值 val rdd = sc.parallelize(Seq(1,2,3)) // 依然可以生成新的RDD,只是需要用新的变量来存储 val doubledRdd = rdd.map(_ * 2) // rdd = doubledRdd // 这行代码会报错,因为val变量的引用不可变
你看,就算用val,RDD的变换操作还是会生成新的RDD,只是我们不能改变原有变量的指向罢了。
总结一下
RDD的不可变性是RDD对象自身的属性(一旦创建就不能修改内部状态),而var/val是变量引用的属性(决定变量能不能指向新的对象)——这是两个完全独立的概念,所以用var声明RDD变量完全不违背RDD的不可变性原则。
内容的提问来源于stack exchange,提问作者Noob_developer
相关产品推荐
相关产品推荐

