Iceberg Liquid Clustering
Liquid Clustering是Iceberg表的一种数据组织策略。指定聚类列(clustering column)后,Liquid Clustering会将聚类列值相近的数据文件在物理上归为一组,从而提高查询时的数据读取效率。Iceberg以Cube为基本管理单元来组织这些归组后的数据文件。
Liquid Clustering是分区表的替代方案。Liquid Clustering不依赖固定分区目录,写入时自动按聚类列聚簇并增量维护数据布局。Liquid Clustering随数据分布变化自适应调整。当表中数据发生变化时,可局部优化数据排布,无需对全表重新分区。
| 维度 | 分区表 | Liquid Clustering |
|---|---|---|
| 聚类维度 | 分区键受基数限制,一维为主。 | 聚类键支持2~4个字段,高基数与低基数可混合,无目录拆分、无元数据膨胀。 |
| 布局演进 | 修改分区键需重写历史数据。 | 修改聚类键仅影响新写入数据;聚类列不匹配的旧cube默认保留,仅需要时通过rewrite-all重写,无全表迁移成本。 |
| 多维过滤 | 裁剪仅沿分区字段进行。 | 文件级data skipping,多个聚类键同时参与跳过,多维查询大幅减少扫描量。 |
| 文件大小维护 | 完全依赖人工调度compaction。 | 增量维护:按cube健康度判定(小于min-cube-size的Partial cube合并、超target的拆分),只重写不健康cube,其余整体跳过。 |
| 元数据与目录 | 分区目录随基数膨胀。 | 无物理分区目录;cube映射收敛为单个sidecar JSON,并提供liquid_cubes元数据表直观观测cube健康状态。 |
| 排序与运维 | 分区裁剪与Z-order两套机制叠加。 | 内置Hilbert曲线排序保证数据局部性,统一通过rewrite_data_files入口执行,与sort/zorder策略互斥,避免多套运维逻辑混用。 |
适用场景
- 表中存在高基数列,并且查询条件频繁涉及此类列。
- 表中存在严重的数据倾斜。
- 表中数据量快速增长,需要持续维护调优。
约束与限制
- 需要Iceberg表format-version=2或更高版本。
- 需要2~4个聚类列,少于2个或多于4个不支持。
- Iceberg表必须是非分区表。Liquid Clustering 是分区表的替代方案。
- 聚类列不允许重复。
- 不能从schema中删除聚类列。
- binpack/sort/zorder策略以及partial-progress模式与启用Liquid clustering的Iceberg表不兼容。
Cube
Cube是Liquid Clustering组织数据的基本管理单元,指在同一套聚类规则下产出的一批数据文件的逻辑分组。每一个Cube包含以下内容:
- Cube ID:UUID全局唯一标识。
- 数据文件列表:归属该Cube的全部数据文件(data file)。
- 聚类列标识:生成该Cube时使用的聚类列,以字段ID(field ID)存储。
- 总数据量:Cube内全部数据文件的字节总大小。
- 关联快照:生成该Cube对应的Iceberg快照(snapshot)。
Cube健康度(Cube Health)
随着数据不断写入,Cube中的文件可能变得分散或不再符合当前聚类规范。为此,Iceberg会将每个Cube与表当前生效的聚类规范(clustering specification)进行比对,输出Cube的健康状态。健康状态用于反映该Cube内部数据的聚类有效性,后台任务据此判断是否需要对该Cube执行重聚类重写操作。
| 健康状态 | 含义 | 是否会被重写 |
|---|---|---|
| 健康(Healthy) | Cube总大小大于等于配置项min-cube-size-bytes,且Cube的聚类列与表当前聚类规范完全一致。 | 仅当rewrite-all=true时才会重写。 |
| 过小(Partial) | Cube总大小小于min-cube-size-bytes,体积过小,需要被合并重写以提高读取效率。 | 始终会被重写。 |
| 聚类列不匹配(column_mismatch) | 该Cube创建时使用的聚类列与表当前生效的聚类规范不一致。 | 仅当rewrite-all=true时才会重写。 |
配置项
Liquid Clustering完全通过Iceberg表属性进行配置。
| 表属性 | 含义 | 默认值 |
|---|---|---|
| write.liquid-clustering.columns | 聚类列列表,多个列使用逗号分隔。 | 无 |
| write.liquid-clustering.target-cube-size-bytes | 每个Cube的目标大小,单位字节。文件会被归组为Cube,单个Cube大小建议不超过该值。 | 10GB |
| write.liquid-clustering.min-cube-size-bytes | Cube的最小阈值,单位字节。小于该值的Cube会被标记partial健康状态并触发重写。 | 5GB |
聚类列选择指南
指定聚类列时,应优先选择查询过滤条件中最频繁使用的列。多个聚类列可以按任意顺序定义;如果两个列高度相关,仅需将其中一列作为聚类列即可。
聚类列支持的数据类型如下:
- INTEGER
- LONG
- FLOAT
- DOUBLE
- DECIMAL
- DATE
- TIMESTAMP
- STRING