Scala Spark缓存RDD而不被要求

Scala Spark缓存RDD而不被要求,scala,apache-spark,Scala,Apache Spark,根据Spark文档,如果我们不“缓存”给定的RDD,那么每次我们引用它时,RDD背后的业务逻辑(图)都会得到评估。但在实践中,当我尝试使用Spark shell时,我发现即使我们没有显式缓存,仍然在使用“内存中”副本。为什么Spark cache RDD在我们没有要求的情况下会这样做?我在windows上使用Spark的独立模式,这与此有关吗 让我描述一下我做了什么。我创建了一个简单的文本文件,如下所示:- key1,value1 key2,value2 key3,value3 现在,我从Sp

根据Spark文档,如果我们不“缓存”给定的RDD,那么每次我们引用它时,RDD背后的业务逻辑(图)都会得到评估。但在实践中,当我尝试使用Spark shell时,我发现即使我们没有显式缓存,仍然在使用“内存中”副本。为什么Spark cache RDD在我们没有要求的情况下会这样做?我在windows上使用Spark的独立模式,这与此有关吗

让我描述一下我做了什么。我创建了一个简单的文本文件,如下所示:-

key1,value1
key2,value2
key3,value3
现在,我从Spark的Scala外壳创建了一个RDD,如下所示:-

val rdd = sc.textFile("sample.txt").map(line => line.split(",")).map(line => (line(0),line(1)))
现在,当我在此RDD上执行以下操作时,我得到值1:-

rdd.lookup("key1")
到目前为止一切都很好。现在,我打开原始源文件并向其中添加一个条目,如下所示:-

key4,value4
我保存文件。现在,从同一个shell(我还没有退出shell)启动以下操作:-

rdd.lookup("key4")
它返回空列表,所以基本上是说它没有找到键4的条目。这意味着Spark仍在使用它显然保存在内存中的旧版本。否则,如果您所说的是正确的,它应该从头开始评估RDD的完整业务逻辑,在这种情况下,它将获得key4,value4。但它完全不知道文件中的这一行。为什么会这样?我显然还没有缓存RDD,但它仍然引用了文件的旧版本


谢谢

您确定已在hdfs中编辑并上载此新文本文件吗?
我重复了你的步骤:在hdfs上上传文件,计算rdd,删除旧文件,用新行上传新文件,然后运行查找操作-它返回新结果

我可以用Apache Spark 1.3.0重现这种行为。我还想用1.4.0复制它,因为它对阶段中发生的转换有很好的可见性。但是在Spark 1.4.0
rdd.lookup(“key4”)
中有效


我认为这意味着该行为是由bug引起的。我找不到bug编号。

这不是bug,而是Spark shell提供的功能。我能够在最新的Spark-1.5.0-SNAPSHOT中看到相同的行为

Spark guys创建shell的想法是使用一些交互式控制台,以便在预加载的数据集上进行一些快速计算。 在内核下,它使用scalarepl,一旦声明,它就会将对象保存在JVM中


请参阅第4节(解释器集成)

您使用的Spark版本是什么?你也试过使用本地文件吗?(我想OP是在试验本地文件。)1.3.1,独立模式,hdfs文件系统在
core site.xml
中配置了属性
fs.defaultFS
。我在Windows上对本地文件系统使用Spark 1.4.0(“Spark Standalone”也是由Spark Shell启动的)。但即使在这种情况下,我相信它的表现应该不会有任何不同。Spark不应该在我们不要求的情况下缓存它。它应该在每次引用RDD时执行沿袭,除非它被缓存。我没看到它发生。你用的是什么版本的Spark?啊,奇怪!您是否尝试使用本地文件或HDFS?我无法在本地磁盘上使用1.4.0进行复制。如果可以,我建议您查看作业Spark UI上的DAG可视化。它应该告诉你它是否认为它正在读取文件。我只使用本地文件。事实上,我已经在我的Windows笔记本电脑上安装了这个。让我试着按照你的建议检查UI。我试着检查这个作业的spark UI上的DAG可视化,即rdd.lookup(“key4”),它显示它正在从文件读取。但结果仍然是,即使在创建RDD后将其添加到文件中,它也无法获取key4、value4。我注意到的另一件有趣的事情是,即使我缓存某些RDD并在shell中连续两次对其调用某些“操作”,最新作业的DAG可视化也仍然显示它正在从源文件读取。这是否意味着“缓存”在本地不起作用?也许这意味着我只是误解了可视化:)。对不起,我现在不能再深入探讨这个问题了。作为一种解决方法,我认为您可以从零开始使用新的RDD。如果没有缓存,那么我认为重新使用RDD对性能没有好处。