涵盖 Spark rewrite_data_files 与 AWS S3 Tables 自动 Compaction | 2026-07
Apache Iceberg 作为一种高性能的表格式(Table Format),支持在对象存储上进行高效的增量写入。但频繁的小文件写入会导致查询性能下降,因此需要 Compaction(文件压缩/合并)来优化数据文件布局。
核心目标:将大量小文件合并为少量大文件,优化查询时的 I/O 效率,同时避免对已经合理大小的文件进行重复操作。
Spark 通过 Iceberg 的 rewrite_data_files 存储过程来执行 Compaction。默认使用 Bin-Packing 策略。
CALL catalog.system.rewrite_data_files(
table => 'db.my_table',
strategy => 'binpack',
options => map(
'target-file-size-bytes', '134217728', -- 128MB
'min-file-size-bytes', '100663296', -- 96MB (75%)
'max-file-size-bytes', '241591910' -- ~230MB (180%)
)
)
Bin-Packing 策略的核心在于只选择"不合理大小"的文件进行重写:
min-file-size-bytes → 太小,选为候选 ✅max-file-size-bytes → 太大,选为候选(将被拆分)✅min-file-size-bytes ≤ 文件大小 ≤ max-file-size-bytes → 合理大小,跳过 ❌关键结论:已经合并到目标大小范围内的文件,在后续 rewrite_data_files 调用时不会再参与合并。
| 参数 | 值 |
|---|---|
| target-file-size-bytes | 128 MB |
| min-file-size-bytes (75%) | 96 MB |
| max-file-size-bytes (180%) | ~230 MB |
Step 1 — 初始状态
10 个文件 × 10MB = 100MB 总数据
所有文件 (10MB) < min (96MB) → 全部选为候选
Step 2 — 第一次合并后
1 个文件 × 100MB(实际合并结果,接近但略小于 target)
100MB 落在 [96MB, 230MB] 范围内 → 标记为"合理大小"
Step 3 — 新增写入
1 × 100MB + 10 × 10MB = 200MB 总数据,11 个文件
Step 4 — 第二次合并
100MB 文件 → 在合理范围内 → ❌ 不参与 10 × 10MB 文件 → 低于 min → ✅ 参与合并 结果:1 × 100MB(原) + 1 × 100MB(新合并) = 2 个文件
| 参数 | 默认值 | 说明 |
|---|---|---|
target-file-size-bytes |
512 MB | 合并后的目标文件大小 |
min-file-size-bytes |
target × 75% | 低于此值的文件被视为"太小",参与合并 |
max-file-size-bytes |
target × 180% | 高于此值的文件被视为"太大",被拆分 |
min-input-files |
5 | 一个分组至少需要 N 个文件才会触发重写 |
max-concurrent-file-group-rewrites |
5 | 并行重写的文件组数 |
partial-progress.enabled |
false | 是否允许部分提交(大表推荐开启) |
delete-file-threshold |
2147483647 | 关联 delete file 超过此数的数据文件强制重写 |
-- Sort 策略示例 CALL catalog.system.rewrite_data_files( table => 'db.my_table', strategy => 'sort', sort_order => 'event_time ASC NULLS LAST, user_id ASC' )
AWS S3 Tables 提供托管的自动 Compaction 服务,无需用户手动触发:
| 配置项 | 默认值 | 说明 |
|---|---|---|
| 策略 | Bin-Pack | 与 Iceberg 社区一致 |
| 启用状态 | 默认开启 | 表创建后自动生效 |
| 目标文件大小 | 512 MB | 可通过 API 调整 |
| 调度频率 | 服务自动管理 | 无需配置 cron |
aws s3tables put-table-maintenance-configuration \
--table-bucket-arn arn:aws:s3tables:region:account:bucket/my-bucket \
--namespace my_namespace \
--name my_table \
--type icebergCompaction \
--value '{
"status": "enabled",
"settings": {
"icebergCompaction": {
"targetFileSizeBytes": 134217728
}
}
}'
| S3 Tables 自动 Compaction | 手动 Spark rewrite_data_files | |
|---|---|---|
| 策略 | 仅 bin-pack | bin-pack / sort / z-order |
| 频率 | 服务自动调度 | 用户自行触发 |
| 可定制性 | 有限(目标大小) | 完全可配 |
| 成本 | 包含在 S3 Tables 费用中 | 需额外 Spark/EMR 集群 |
| 适用场景 | 常规小文件合并 | 需要排序优化或精细控制 |
delete-file-threshold=10,每 15-30 分钟执行一次 compaction,防止 delete files 堆积导致 Redshift MaxMessageSize 错误partial-progress.enabled=true,避免单次事务过大导致冲突sort 策略按查询高频列排序,平时使用 binpackmin-file-size-bytes 设为 target-file-size-bytes,除非明确需要全量重组