2016-05-17 59 views
2

我正在提交一个spark工作(spark-submit)。是否会自动启动缓存rdds?

问题

我加载由HDFS读取的Avro文件的RDD。
然后我过滤rdd &数它(作业1)。
然后我再次使用不同的标准对其进行过滤并计算它(作业2)。

  • 在日志中,我看到FileInputFormat第一次读取60个文件。但它不会在第二次读取任何文件。
  • 另外,当我做rdd.toDebugString我没有看到被缓存的父rdd。

详细

下面是代码:

JavaRdd<Record> records = loadAllRecords(); 
JavaRDD<Record> type1Recs = records.filter(selectType1()); 
JavaRDD<Record> type2Recs = records.filter(selectType2()); 
log.info(type1Recs.count()); 
log.info(type2Recs.count()); 

当我看到第一个计数RDD调试信息:

..... 
    ..... 
    | MapPartitionsRDD[2] at filter at xxxx.java:61 [] 
    | NewHadoopRDD[0] at newAPIHadoopRDD at xxxxx.java:64 [] 

当我看第二个计数的rdd调试信息:

..... 
    ..... 
    | MapPartitionsRDD[5] at filter at EventRepo.java:61 [] 
    | NewHadoopRDD[0] at newAPIHadoopRDD at xxxxx.java:64 [] 

如果我被抓NewHadoopRDD必须在调试字符串关联到它的一些醒目信息...

不过,我不知道,在这两种情况下,RDD作为​​称。 [0]这个意思是说在这个上下文中的id是什么?我认为RDD有句柄,所以我不确定重复使用同一个句柄的意义是什么?

当我做的第一count我在日志中看到:

FileInputFormat: Total input paths to process : 60 

但我没有看到一个类似的日志第二计数。 records Rdd不应该重新加载吗?

最后第二计数大于这使我相信数据是内存中的第一快...

回答

3

对于此行,FileInputFormat: Total input paths to process : 60,它属于RDD的元数据。这个输出在NewHadoopRDD.getPartitions。这很懒,但只运行一次。你可以说RDD的元数据被缓存了。但是这个RDD的数据(文件中的数据)没有被缓存。

+0

啊有趣!所以实际上它重新读取数据呢? – hba

+0

是的,除非你手动调用RDD.cache。 – zsxwing

2

是否会自动启用缓存rdds?

有时候,是的。在洗牌的情况下,RDD会自动缓存。例如,您可能在火花Web UI中观察到“跳过的阶段”。

请参见:https://spark.apache.org/docs/1.5.0/programming-guide.html#shuffle-operations

在其他情况下,你将需要调用rdd.cache或其变体。

+0

我开始看到这些“跳过的阶段”,它们在我进行完全外连接之前就已经发生了...所以实际上它会自动执行缓存......但是我没有在您拥有的文档中看到这一点链接在你的答案... – hba