TL;DR
- 场景: 对比 Cube4(优化后)与 Cube7(未优化)的体积与精度差异
- 结论: Cube7 体积明显大于 Cube4,维度越多 Cuboid 指数增长越显著
- 产出: 聚合组配置、RowKey 设计、编码选择、分片策略
Cube7 vs Cube4 对比
实验设计
- Cube4: 使用聚合组、必要维度、层级维度、联合维度优化
- Cube7: 所有维度设置为 Normal,无优化
- 数据量: 相同
结果
| Cube | Cuboid 数量 | 体积 | 膨胀率 |
|---|---|---|---|
| Cube4(优化) | 较少 | 较小 | < 500% |
| Cube7(未优化) | 指数增长 | 较大 | > 1000% |
Aggregation Group(聚合组)
作用
随着维度数目增加,Cuboid 会指数级增长。通过聚合组可有效控制预计算规模。
默认行为
默认情况下,所有维度在同一聚合组。
建议
维度 >15 时建议拆分多个聚合组。
配置示例
Group 1: dt, region_id, product_id
Group 2: dt, channel_id, category_id
Mandatory Dimension(强制维度)
作用
总会出现在 WHERE 或 GROUP BY 中的维度。配置后可减少不包含该维度的 Cuboid。
配置
在 Kylin Cube Designer 中勾选 Mandatory。
示例
- dt(日期):几乎所有查询都会按日期筛选
- status(状态):总是作为过滤条件
Hierarchy Dimension(层级维度)
作用
具有层级关系的维度(如国家→省→市),同一层级只会预计算最细粒度组合。
配置
在 Cube Designer 中设置层级维度:
- dim_region.country
- dim_region.province
- dim_region.city
效果
对于 {国家, 省, 市} 层级维度:
- 预计算:国家、省、市(最细粒度)
- 不预计算:国家+省、省+市(被包含)
Joint Dimension(联合维度)
作用
将多个维度视为一体,要么同时出现要么均不出现。
适用场景
- 总是共同查询的维度
- 基数很低的维度组合
配置
在 Cube Designer 中勾选 Joint。
示例
- {province, city}:总是同时使用
- {channel_type, channel_name}:低基数组合
RowKey 设计
映射关系
- Cuboid 维度 → HBase Rowkey
- 指标 → HBase Value
编码方式
| 编码 | 适用场景 |
|---|---|
| Dictionary | 低基数枚举值,自动映射为字节 |
| boolean | true/false |
| date | 日期类型 |
| time | 时间类型 |
| fixed_length | 定长字符串 |
RowKey 顺序建议
- Mandatory - 强制维度优先
- 高频过滤 - 经常出现在 WHERE 条件
- 高基数 - 基数大的维度
- 低基数 - 基数小的维度
示例
RowKey 顺序: dt (Mandatory) > region_id (高频) > product_id (高基数) > category_id (低基数)
分片(ShardBy)
作用
选择高基数列作为分片列,使数据均匀分散,提高并行性。
配置
在 Cube Designer 中设置 ShardBy 字段。
示例
- product_id:高基数,分散效果好
- order_id:唯一ID,完美分片
精度/稀疏度分析
CubeStatsReader 输出
kylin.sh org.apache.kylin.engine.mr.common.CubeStatsReader cube_name
输出指标
- HII Precision: 估计精度
- Total Cuboids: 总 Cuboid 数量
- Total Rows: 总行数
- Total Size: 总大小
- Per Cuboid 详情: 每个 Cuboid 的行数/体积
错误速查
| 症状 | 根因定位 | 修复 |
|---|---|---|
| 构建慢 | Cuboid 过多 | 配置聚合组、必要/层级/联合维度 |
| 查询慢 | RowKey 顺序不当 | 调整编码与顺序 |
| 存储大 | 未使用字典编码/分片不均 | 优化编码,选择合适分片列 |
| 命中率低 | 查询模式与 Cube 设计不匹配 | 分析查询日志,调整维度配置 |
| OOM | 维度组合爆炸 | 拆分聚合组,减少维度 |