返回首页

Iceberg 优化:排序和删除向量

本文涵盖 Apache Iceberg 表的优化:用于数据跳过的排序、列统计信息配置以及切换到 v3 中的删除向量。为 Spark 提供代码示例和效率指标。

Iceberg 优化:从排序到删除向量
Advertisement 728x90

优化 Iceberg 表:排序、统计与删除向量

在写入 Iceberg 表时对数据进行排序,可以让执行引擎基于清单文件中的最小/最大统计信息跳过不必要的文件。如果不排序,文件中的值范围会重叠,导致即使有严格过滤条件也需要读取所有数据。

创建表并写入时不排序的示例:

spark.sql("""
CREATE TABLE habr.paper.write_ordered (
  id INT,
  name STRING,
  event STRING
)
USING ICEBERG
""")
data = [(i, f"name_{i}", f"event_{i}") for i in range(1, 1000000)]
df = spark.createDataFrame(data, ["id", "name", "event"]).repartition(16)
df.writeTo("habr.paper.write_ordered").append()

查询元数据显示混乱的范围:

Google AdInline article slot

| id_min | id_max | file_path |

|--------|--------|-----------|

| 2 | 999994 | ... |

Google AdInline article slot

| 43 | 999988 | ... |

使用 id < 100000 的过滤器将读取所有文件。

启用排序:

Google AdInline article slot
spark.sql("""
ALTER TABLE habr.paper.write_ordered
WRITE ORDERED BY id
""")

重写后得到顺序范围:

| id_min | id_max | file_path |

|--------|--------|-----------|

| 1 | 196479 | ... |

| 196480 | 395983 | ... |

现在,使用 id < 196470 的过滤器只读取一个文件。

配置列统计收集

Iceberg 默认收集所有列的完整最小/最大/截断统计信息,这会增加写入时间而对查询无益。在典型表中,过滤通常发生在 1-2 列上,其他列的统计信息是不必要的。

具有 10 列的扁平表示例:

spark.sql("""
CREATE TABLE habr.paper.typical_flat_table (
  id INT,
  name STRING,
  col_1 STRING,
  col_2 STRING,
  col_3 STRING,
  col_4 STRING,
  col_5 STRING,
  col_6 STRING,
  col_7 STRING,
  col_8 STRING
)
USING ICEBERG
""")

通过 TBLPROPERTIES 配置:

spark.sql("""
ALTER TABLE habr.paper.typical_flat_table SET TBLPROPERTIES (
    'write.metadata.metrics.default' = 'counts',
    'write.metadata.metrics.column.id' = 'full',
    'write.metadata.metrics.column.col_1' = 'none'
)
""")
  • default: 'counts' — 所有列仅统计行数
  • full: 关键过滤列(如 id)的最小/最大 + 截断统计
  • none: 未使用列的统计禁用

这减少了写入开销和元数据量,同时不会丢失关键字段上的数据跳过能力。

MoR 中的向量化删除

在合并读取策略中,读取性能取决于删除应用机制。经典的删除文件需要与数据进行连接。

删除文件的类型:

  • 等值删除: 删除规则(在 v3 中已弃用)
  • 位置删除: 文件中的行位置

在 Iceberg v3 中,位置删除演变为基于 Puffin 格式的删除向量。删除向量是一个位图掩码,可在一个周期内应用于数据文件。

位置删除示例:

| file_path | pos |

|-----------|-----|

| ...parquet | 873 |

| ...parquet | 230 |

替代连接操作:加载位图 + 逻辑与运算。这可以将高删除率下的 MoR 表读取速度提升 5-10 倍。

删除向量特别适用于:

  • 频繁更新的批处理 ETL
  • 具有缓慢变化维度的表
  • 使用 MoR 的流处理

关键要点

  • 在可过滤列上使用 WRITE ORDERED BY 排序,减少分析中可读文件的数量
  • 配置 write.metadata.metrics.* 最小化写入开销,同时保留数据跳过功能
  • Iceberg v3 中的删除向量取代位置删除,通过位图加速 MoR 读取
  • 优化无需更改查询或 ETL 逻辑即可生效
  • 效果累积:更少的文件、更少的元数据、降低对象存储负载

— Editorial Team

Advertisement 728x90

继续阅读