本文介绍了使用 Delta Lake 时的最佳做法。
下面是适用于大多数 Delta Lake 工作负荷的一般建议:
使用 Unity 目录托管表。 请参阅使用托管表。
使用液体聚类分析。 请参阅将液态聚类分析用于 Delta 表。
删除并在同一位置重新创建表时,应始终使用
CREATE OR REPLACE TABLE
语句。 请参阅删除或替换 Delta 表。
Databricks 建议在升级到新的 Databricks Runtime 版本时,从 Spark 配置和表属性中移除大多数显式旧版 Delta 配置。 旧版配置可以防止 Databricks 引入的新优化和默认值应用于已迁移的工作负荷。
Databricks 建议经常运行 OPTIMIZE 命令来压缩小文件。
注意
此操作不会移除旧文件。 若要移除它们,请运行 VACUUM 命令。
Databricks 不建议出于以下原因使用 Spark 缓存:
- 丢失的任何数据跳过都可能归因于在缓存的
DataFrame
顶部添加的其他筛选器。 - 如果使用其他标识符访问表,则可能不会更新缓存的数据。
Delta Lake 会自动处理以下操作。 不应手动执行以下操作:
-
REFRESH TABLE
:Delta 表始终返回最新信息,因此无需在更改后手动调用REFRESH TABLE
。 - 添加和删除分区:Delta Lake 会自动跟踪表中存在的分区集,并在添加或删除数据时更新列表。 因此,无需运行
ALTER TABLE [ADD|DROP] PARTITION
或MSCK
。 -
加载单个分区:不需要直接读取分区。 例如,无需运行
spark.read.format("parquet").load("/data/date=2017-01-01")
。 请改用WHERE
子句进行数据跳过,例如spark.read.table("<table-name>").where("date = '2017-01-01'")
。 - 不要手动修改数据文件:Delta Lake 使用事务日志自动提交对表的更改。 不要直接修改、添加或删除 Delta 表中的 Parquet 数据文件,因为这可能会导致数据丢失或表损坏。
可使用以下方法缩短合并所用的时间:
减少匹配项的搜索空间:默认情况下,
merge
操作会搜索整个 Delta 表以在源表中查找匹配项。 加速merge
的一种方法是通过在匹配条件中添加已知约束来缩小搜索范围。 例如,假设你有一个由country
和date
分区的表,并且你希望使用merge
更新最后一天和特定国家/地区的信息。 添加以下条件可加快查询速度,因为它仅在相关分区中查找匹配项:events.date = current_date() AND events.country = 'USA'
此外,该查询还会减少与其他并发操作发生冲突的机会。 有关更多详细信息,请参阅 Azure Databricks 上的隔离级别和写入冲突。
压缩文件:如果数据存储在许多小文件中,则读取数据以搜索匹配项可能会变慢。 可以将小文件压缩为更大的文件,以提高读取吞吐量。 有关详细信息,请参阅优化数据文件布局。
控制写入的数据重新分区:
merge
操作对数据进行多次重新分配以计算和写入更新的数据。 用于随机排列的任务的数量由 Spark 会话配置spark.sql.shuffle.partitions
控制。 设置此参数不仅可以控制并行度,还可以确定输出文件的数量。 增大该值可提高并行度,但也会生成大量较小的数据文件。启用优化写入:对于已分区表,
merge
生成的小文件数量远大于随机分区的数量。 这是因为每个洗牌任务都可以在多个分区中写入多个文件,并可能导致性能瓶颈。 可以通过启用优化写入来减少文件数量。 请参阅 Azure Databricks 上 Delta Lake 的优化写入。调整表中的文件大小:Azure Databricks 可以自动检测 Delta 表是否在频繁执行重写文件的
merge
操作,并可能会减小重写文件的大小,以备将来执行更多文件重写操作。 有关详细信息,请参阅有关调整文件大小的部分。低随机排列合并:低随机排列合并提供了
MERGE
的优化实现,可为大多数常见工作负载提供更好的性能。 此外,它还保留了现有的数据布局优化,例如对未修改数据的进行 Z 排序。