Databricks 上的 Spark - 缓存 Hive table
Spark on Databricks - Caching Hive table
我们将事实 table(30 列)存储在 S3 上的 parquet 文件中,还在该文件上创建了 table 并随后将其缓存。 Table 是使用以下代码片段创建的:
val factTraffic = spark.read.parquet(factTrafficData)
factTraffic.write.mode(SaveMode.Overwrite).saveAsTable("f_traffic")
%sql CACHE TABLE f_traffic
我们运行 对此 table(文件)进行了许多不同的计算,并且正在寻找缓存数据以便在后续计算中更快访问的最佳方法。问题是,出于某种原因,从 parquet 读取数据并进行计算然后从内存访问它会更快。一个重要的注意事项是我们不会利用每一列。通常,每次计算大约 6-7 列,每次计算不同的列。
有没有办法将此 table 缓存在内存中,以便我们可以比从镶木地板读取更快地访问它?
缓存中的materalize dataframe,你应该这样做:
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
另见
但这是否有意义值得怀疑,因为 parquet 是一种列式文件格式(意味着投影非常有效),如果您需要为每个查询使用不同的列,那么缓存将无济于事。
听起来你 运行 在 Databricks 上,所以你的查询可能会自动受益于 Databricks IO Cache. From the Databricks docs:
The Databricks IO cache accelerates data reads by creating copies of remote files in nodes’ local storage using fast intermediate data format. The data is cached automatically whenever a file has to be fetched from a remote location. Successive reads of the same data are then executed locally, which results in significantly improved reading speed.
The Databricks IO cache supports reading Parquet files from DBFS, Amazon S3, HDFS, Azure Blob Storage, and Azure Data Lake. It does not support other storage formats such as CSV, JSON, and ORC.
Databricks IO 缓存在 Databricks Runtime 3.3 或更新版本上受支持。默认情况下是否启用它取决于您为集群上的工作人员选择的实例类型:目前它为 Azure Ls 实例和 AWS i3 实例自动启用(有关完整详细信息,请参阅 AWS and Azure 版本的 Databricks 文档).
如果此 Databricks IO 缓存生效,则显式使用具有未转换基数的 Spark 的 RDD 缓存 table 可能会损害查询性能,因为它将存储数据的第二个冗余副本(并支付往返解码费用和编码以便这样做)。
如果您正在缓存转换后的数据集,则显式缓存仍然有意义,例如过滤后显着减少数据量,但如果您只想缓存大型且未转换的基关系,那么我个人建议依赖 Databricks IO 缓存并避免使用 Spark 的 built-in RDD 缓存。
查看完整的 Databricks IO 缓存文档了解更多详细信息,包括有关缓存预热、监控以及 RDD 和 Databricks IO 缓存的比较的信息。
我们将事实 table(30 列)存储在 S3 上的 parquet 文件中,还在该文件上创建了 table 并随后将其缓存。 Table 是使用以下代码片段创建的:
val factTraffic = spark.read.parquet(factTrafficData)
factTraffic.write.mode(SaveMode.Overwrite).saveAsTable("f_traffic")
%sql CACHE TABLE f_traffic
我们运行 对此 table(文件)进行了许多不同的计算,并且正在寻找缓存数据以便在后续计算中更快访问的最佳方法。问题是,出于某种原因,从 parquet 读取数据并进行计算然后从内存访问它会更快。一个重要的注意事项是我们不会利用每一列。通常,每次计算大约 6-7 列,每次计算不同的列。
有没有办法将此 table 缓存在内存中,以便我们可以比从镶木地板读取更快地访问它?
缓存中的materalize dataframe,你应该这样做:
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
另见
但这是否有意义值得怀疑,因为 parquet 是一种列式文件格式(意味着投影非常有效),如果您需要为每个查询使用不同的列,那么缓存将无济于事。
听起来你 运行 在 Databricks 上,所以你的查询可能会自动受益于 Databricks IO Cache. From the Databricks docs:
The Databricks IO cache accelerates data reads by creating copies of remote files in nodes’ local storage using fast intermediate data format. The data is cached automatically whenever a file has to be fetched from a remote location. Successive reads of the same data are then executed locally, which results in significantly improved reading speed.
The Databricks IO cache supports reading Parquet files from DBFS, Amazon S3, HDFS, Azure Blob Storage, and Azure Data Lake. It does not support other storage formats such as CSV, JSON, and ORC.
Databricks IO 缓存在 Databricks Runtime 3.3 或更新版本上受支持。默认情况下是否启用它取决于您为集群上的工作人员选择的实例类型:目前它为 Azure Ls 实例和 AWS i3 实例自动启用(有关完整详细信息,请参阅 AWS and Azure 版本的 Databricks 文档).
如果此 Databricks IO 缓存生效,则显式使用具有未转换基数的 Spark 的 RDD 缓存 table 可能会损害查询性能,因为它将存储数据的第二个冗余副本(并支付往返解码费用和编码以便这样做)。
如果您正在缓存转换后的数据集,则显式缓存仍然有意义,例如过滤后显着减少数据量,但如果您只想缓存大型且未转换的基关系,那么我个人建议依赖 Databricks IO 缓存并避免使用 Spark 的 built-in RDD 缓存。
查看完整的 Databricks IO 缓存文档了解更多详细信息,包括有关缓存预热、监控以及 RDD 和 Databricks IO 缓存的比较的信息。