# Iceberg Liquid Clustering
Liquid Clustering是Iceberg表的一种数据组织策略。指定聚类列（clustering column）后，Liquid Clustering会将聚类列值相近的数据文件在物理上归为一组，从而提高查询时的数据读取效率。Iceberg以Cube为基本管理单元来组织这些归组后的数据文件。
Liquid Clustering是分区表的替代方案。Liquid Clustering不依赖固定分区目录，写入时自动按聚类列聚簇并增量维护数据布局。Liquid Clustering随数据分布变化自适应调整。当表中数据发生变化时，可局部优化数据排布，无需对全表重新分区。
表1分区表与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执行重聚类重写操作。
表2Cube的健康状态 
| 健康状态                   | 含义                                                      | 是否会被重写                     |
|:---|:---|:---|
| 健康（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表属性进行配置。
表3配置项 
| 表属性                                             | 含义                                             | 默认值   |
|:---|:---|:---|
| 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
 
