Spark在Databricks上 - 缓存Hive表

时间:2018-03-19 14:25:33

标签: apache-spark apache-spark-sql spark-dataframe databricks

我们在S3上的镶木地板文件中存储了事实表(30列),并在此文件上创建了表格,然后将其缓存。使用此代码段创建表:

val factTraffic = spark.read.parquet(factTrafficData)
factTraffic.write.mode(SaveMode.Overwrite).saveAsTable("f_traffic")
%sql CACHE TABLE f_traffic

我们在此表(文件)上运行了许多不同的计算,并且正在寻找缓存数据的最佳方法,以便在后续计算中更快地访问。问题是,由于某种原因,从拼花地板读取数据会更快,然后进行计算,然后从内存中访问它。一个重要的注意事项是我们不使用每一列。通常,每次计算大约6-7列,每次不同的列。

有没有办法在内存中缓存此表,以便我们可以更快地访问它,然后从镶木地板中读取?

2 个答案:

答案 0 :(得分:3)

听起来您正在Databricks上运行,因此您的查询可能会自动受益于Databricks IO Cache。来自Databricks docs

  

Databricks IO缓存通过使用快速中间数据格式在节点的本地存储中创建远程文件的副本来加速数据读取。每当必须从远程位置获取文件时,数据都会自动缓存。然后在本地执行相同数据的连续读取,这将显着提高读取速度。

     

Databricks IO缓存支持从DBFS,Amazon S3,HDFS,Azure Blob存储和Azure Data Lake读取Parquet文件。它不支持其他存储格式,如CSV,JSON和ORC。

Databricks Runtime 3.3或更高版本支持Databricks IO Cache。它是否默认启用取决于您为群集上的工作程序选择的实例类型:当前它是为Azure Ls实例和AWS i3实例自动启用的(请参阅AWSAzure版本的Databricks文档了解完整的详细信息。)

如果此Databricks IO缓存生效,那么显式使用Spark的RDD缓存与未转换的基表可能会损害查询性能,因为它将存储数据的第二个冗余副本(并支付往返解码和编码以便执行此操作所以)。

如果您正在缓存已转换的数据集,那么显式缓存仍然有意义,例如过滤后显着减少数据量,但如果你只想缓存一个大的未转换的基本关系,那么我个人建议依靠Databricks IO缓存并避免使用Spark的内置RDD缓存。

有关详细信息,请参阅完整的Databricks IO缓存文档,包括有关缓存预热,监视以及RDD和Databricks IO缓存的比较的信息。

答案 1 :(得分:1)

缓存中的materalize数据帧,你应该这样做:

val factTraffic = spark.read.parquet(factTrafficData)
factTraffic.write.mode(SaveMode.Overwrite).saveAsTable("f_traffic")
val df_factTraffic = spark.table("f_traffic").cache
df_factTraffic.rdd.count
// now df_factTraffic is materalized in memory

另见https://stackoverflow.com/a/42719358/1138523

但这是否有意义是有道理的,因为实木复合地板是一种柱状文件格式(意味着投影非常有效),如果每个查询需要不同的列,缓存对你没有帮助。