何时对 Azure Databricks 上的表进行分区

本文概述如何对 Azure Databricks 上的表进行分区,并提供有关何时应该对 Delta Lake 支持的表使用分区的具体建议。 由于内置功能和优化,数据量少于 1 TB 的大多数表都不需要分区。

默认情况下,Azure Databricks 对所有表使用 Delta Lake。 以下建议假设你对所有表使用 Delta Lake。

在 Databricks Runtime 11.2 和更高版本中,Azure Databricks 按照引入时间自动将数据聚类在未分区的表中。 请参阅使用引入时间聚类

是否需要对小型表进行分区?

Databricks 建议不要对数据量少于 1 TB 的表进行分区。

表中每个分区的最小大小是多少?

Databricks 建议所有分区至少包含 1 GB 数据。 包含少量较大分区的表的性能往往优于包含大量较小分区的表。

使用引入时间聚类

通过使用 Delta Lake 和 Databricks Runtime 11.2 或更高版本,创建的未分区表可以自动受益于引入时间聚类。 引入时间为基于日期/时间字段的分区策略提供类似的查询优势,而无需优化数据。

注意

若要在使用 UPDATEMERGE 语句对表执行大量修改时保持引入时间聚类,Databricks 建议使用与引入顺序匹配的列运行 OPTIMIZEZORDER BY。 例如,这可能是包含事件时间戳或创建日期的列。

Delta Lake 和 Parquet 是否共享分区策略?

Delta Lake 使用 Parquet 作为存储数据的主要格式,一些指定了分区的 Delta 表展示了类似于使用 Apache Spark 存储的 Parquet 表的组织方式。 Apache Spark 在以 Parquet 格式保存数据时使用 Hive 样式分区。 Hive 样式分区属于 Delta Lake 协议,工作负载不应依赖此分区策略来与 Delta 表交互。

许多 Delta Lake 功能都打破了有关可能已从 Parquet、Hive 甚至更早的 Delta Lake 协议版本传输回的数据布局的假设。 应始终使用官方支持的客户端和 API 与 Delta Lake 中存储的数据进行交互。

Delta Lake 分区与其他数据湖中的分区有何不同?

虽然 Azure Databricks 和 Delta Lake 是基于 Apache Spark、Parquet、Hive 和 Hadoop 等开源技术构建的,但这些技术中有用的分区动机和策略通常不适用于 Azure Databricks。 如果你选择对表进行分区,请在选择策略之前考虑以下事实:

  • 事务不是按分区边界定义的。 Delta Lake 通过事务日志来确保 ACID,因此你无需按分区分隔一批数据来确保原子发现。
  • Azure Databricks 计算群集的数据位置不与物理媒体相关联。 引入湖屋的数据存储在云对象存储中。 在数据处理期间将数据缓存到本地磁盘存储时,Azure Databricks 将使用基于文件的统计信息来识别要并行加载的最小数据量。

Z 顺序和分区如何协同工作?

可以将 Z 顺序索引与分区一起使用,以加快大型数据集的查询速度。

注意

大多数表都可以利用引入时间聚类来避免 Z 顺序考量和分区优化的需要。

在规划基于分区边界和 Z 顺序的查询优化策略时,请务必牢记以下规则:

  • Z 顺序与 OPTIMIZE 命令配合工作。 不能跨分区边界合并文件,因此 Z 顺序聚类只能在某个分区中发生。 对于未分区的表,可以在整个表中合并文件。
  • 分区仅适用于低基数字段或已知基数字段(例如日期字段或物理位置),而不适用于高基数字段(例如时间戳)。 Z 顺序适用于所有字段,包括高基数字段和可能无限增大的字段(例如交易或订单表中的时间戳或客户 ID)。
  • 不能对用于分区的字段进行 Z 排序。

如果分区有这样的缺点,为何某些 Azure Databricks 功能还会使用分区?

分区有时很有作用,尤其对于极大的表。 分区的许多性能增强都侧重于极大的表(数百 TB 或更大)。

许多客户从基于 Parquet 的数据湖迁移到 Delta Lake。 使用 CONVERT TO DELTA 语句可将基于 Parquet 的现有表转换为 Delta 表,而无需重写现有数据。 因此,许多客户使用继承以前的分区策略的大型表。 Databricks 开发的某些优化技术旨在尽可能利用这些分区,以便抵消未针对 Delta Lake 优化的分区策略的一些潜在缺点。

Delta Lake 和 Apache Spark 是开源技术。 虽然 Databricks 会继续引入可减少对分区的依赖的功能,但开源社区可能会继续构建增大复杂性的新功能。

使用自定义分区是否可以获得比 Azure Databricks 内置优化更好的性能?

一些经验丰富的 Apache Spark 和 Delta Lake 用户能够设计和实现一种性能比引入时间聚类更好的模式。 实现错误的分区策略可能会对下游性能产生非常负面的影响,并且可能需要完全重写数据才能修复。 Databricks 建议大多数用户使用默认设置,以避免造成代价不菲的低效问题。