【问题标题】:How can you find the size of a delta table quickly and accurately?如何快速准确地找到增量表的大小?
【发布时间】:2022-09-29 17:37:59
【问题描述】:

这里的微软文档: https://docs.microsoft.com/en-us/azure/databricks/kb/sql/find-size-of-table#size-of-a-delta-table 建议两种方法:

方法一:

import com.databricks.sql.transaction.tahoe._
val deltaLog = DeltaLog.forTable(spark, \"dbfs:/<path-to-delta-table>\")
val snapshot = deltaLog.snapshot               // the current delta table snapshot
println(s\"Total file size (bytes): ${deltaLog.snapshot.sizeInBytes}\")`

方法二:

spark.read.table(\"<non-delta-table-name>\").queryExecution.analyzed.stats

对于我的表,它们都返回约 300 MB。

但随后在存储资源管理器文件夹统计信息或递归 dbutils.fs.ls 遍历中,我得到了 ~900MB。

因此,这两种方法比从字面上查看每个文件少报 67% 快得多。使用较慢的方法会很好,除非我尝试扩展到整个容器,扫描所有 10 亿个文件和 2.6 PB 需要 55 小时。

那么在 ADLS Gen 2 中获取表大小的最佳方法是什么?如果它适用于不是表格的文件夹,则加分,因为那确实是我需要的数字。 dbutils.fs.ls 是单线程的,并且只适用于驱动程序,因此它甚至不是非常可并行化的。它可以是线程的,但只能在驱动程序中。

  • Delta Lake 有多少个版本?
  • @AlexOtt,不确定我是否理解这个问题——每次有更新或删除操作时都会创建一个版本,对吧?因此,在整个数据湖中,如果不遍历它,它是不确定的。
  • 查看DESCRIBE HISTORY

标签: scala apache-spark azure-databricks delta-lake


【解决方案1】:

deltaLog.snapshot 仅返回当前快照。您可以在表的目录中存在更多文件,这些文件属于已从当前快照中删除/替换的历史版本。

它还返回 0 而不会抱怨非增量路径。所以我使用这段代码来获取数据库级别的摘要:

import com.databricks.sql.transaction.tahoe._
 
val databasePath = "dbfs:/<path-to-database>"
 
def size(path: String): Long =
  dbutils.fs.ls(path).map { fi => if (fi.isDir) size(fi.path) else fi.size }.sum
 
val tables = dbutils.fs.ls(databasePath).par.map { fi =>
  val totalSize = size(fi.path)
  val snapshotSize = DeltaLog.forTable(spark, fi.path).snapshot.sizeInBytes
  (fi.name, totalSize / 1024 / 1024 / 1024, snapshotSize / 1024 / 1024 / 1024)
}
display(tables.seq.sorted.toDF("name", "total_size_gb", "snapshot_size_gb"))

这确实仅在驱动程序上并行化,仍然只是文件列表,因此速度非常快。我承认我没有十亿个文件,但是,如果它对您来说很慢,只需使用更大的驱动程序和tune the number of threads

【讨论】:

    猜你喜欢
    • 2011-12-07
    • 2010-11-25
    • 2015-04-11
    • 1970-01-01
    • 1970-01-01
    • 2014-03-05
    • 2016-09-17
    • 2011-11-12
    • 2017-07-18
    相关资源
    最近更新 更多