缓存不能阻止多个文件罐吗?

时间:2018-06-21 08:01:23

标签: apache-spark dataframe caching

我对DataFram API cache的用法有疑问。考虑以下查询:

val dfA = spark.table(tablename)
.cache

val dfC = dfA
.join(dfA.groupBy($"day").count,Seq("day"),"left")

因此dfA在此查询中使用了两次,因此我认为将其缓存是有益的。但是我对该计划感到困惑,该表仍然被扫描了两次(FileScan出现了两次):

dfC.explain

== Physical Plan ==
*Project [day#8232, i#8233, count#8251L]
+- SortMergeJoin [day#8232], [day#8255], LeftOuter
   :- *Sort [day#8232 ASC NULLS FIRST], false, 0
   :  +- Exchange hashpartitioning(day#8232, 200)
   :     +- InMemoryTableScan [day#8232, i#8233]
   :           +- InMemoryRelation [day#8232, i#8233], true, 10000, StorageLevel(disk, memory, deserialized, 1 replicas)
   :                 +- *FileScan parquet mytable[day#8232,i#8233] Batched: true, Format: Parquet, Location: InMemoryFileIndex[hdfs://tablelocation], PartitionFilters: [], PushedFilters: [], ReadSchema: struct<day:int,i:int>
   +- *Sort [day#8255 ASC NULLS FIRST], false, 0
      +- *HashAggregate(keys=[day#8255], functions=[count(1)])
         +- Exchange hashpartitioning(day#8255, 200)
            +- *HashAggregate(keys=[day#8255], functions=[partial_count(1)])
               +- InMemoryTableScan [day#8255]
                     +- InMemoryRelation [day#8255, i#8256], true, 10000, StorageLevel(disk, memory, deserialized, 1 replicas)
                           +- *FileScan parquet mytable[day#8232,i#8233] Batched: true, Format: Parquet, Location: InMemoryFileIndex[hdfs://tablelocation], PartitionFilters: [], PushedFilters: [], ReadSchema: struct<day:int,i:int>

为什么不缓存表?我正在使用Spark 2.1.1

1 个答案:

答案 0 :(得分:0)

在缓存后尝试使用count(),以便触发一个动作,并在“计算”第二个计划之前完成缓存。

据我所知,第一个动作将触发缓存,但是由于Spark计划不是动态的,因此如果您在缓存后的第一个动作使用了该表两次,则必须将其读取两次(因为它不会缓存)表,直到它执行该操作为止。

如果上述方法不起作用[和/或您遇到了提到的错误],则可能与计划有关,您还可以尝试将DF转换为RDD,然后再转换为RDD(这样,计划将100%准确)。