TL;DR

  • 场景: Cube 维度数量多,Cuboid 指数增长导致构建慢、存储膨胀
  • 结论: 通过衍生维度 + 聚合组 + 膨胀率监控,可有效控制 Cuboid 数量
  • 产出: Cuboid 检查工具、衍生维度配置、膨胀率分析、错误速查

Cuboid 剪枝概述

什么是 Cuboid

Cuboid 特指 Kylin 中在某一种维度组合下所计算的所有数据。以减少 Cuboid 数量为目的的优化统称为 Cuboid 剪枝。

Cuboid 数量计算

4 个维度:2^4 = 16 个 Cuboid
10 个维度:2^10 = 1024 个 Cuboid
20 个维度:2^20 = 1048576 个 Cuboid

剪枝原则

  • 跳过永远不会查询的 Cuboid
  • 跳过能力与其他 Cuboid 接近的 Cuboid
  • 前提:不明显影响查询时间

检查 Cuboid 数量

CubeStatsReader 工具

# 进入 Kylin 安装目录
cd $KYLIN_HOME

# 执行 Cuboid 统计
kylin.sh org.apache.kylin.engine.mr.common.CubeStatsReader wzk_kylin_test_cube_4

输出结果

  • 估计 Cuboid 大小的精度(HII Precision)
  • 总共的 Cuboid 数量
  • Segment 的总行数估计
  • Segment 的大小估计
  • 所有 Cuboid 及分析结果

检查 Cube 大小(Web GUI)

在 Model 页面选择一个 READY 状态的 Cube:

  • Cube Size: Cube 实际大小
  • Expansion Rate: 膨胀率 = Cube大小 / 源数据大小

膨胀率参考

  • 0% ~ 1000%:正常范围
  • > 1000%:需要优化

衍生维度(Derived Dimension)

原理

将维度表的非主键字段设为衍生维度:

  • 不参与 Cuboid 计算
  • 使用维度表主键替代
  • 查询时动态翻译

适用场景

  • 维度表字段与主键有明确映射关系
  • 聚合工作量不大

不适用场景

  • 主键到维度需要大量聚合
  • 影响查询性能

创建衍生维度

在 Kylin Cube Designer 中:

  1. 选择维度表
  2. 找到要设为衍生的列
  3. 勾选 Derived
  4. 保存 Cube

案例对比

日期维度表 dim_date

字段说明
dateid主键
dayofyear年中第几天
dayofmonth月中第几天
day_in_year年中第几天(另一种)
day_in_month月中第几天(另一种)
weekday星期几
week_in_month月中第几周
week_in_year年中第几周
date_type日期类型
quarter季度

注意:日期维度字段不能是 year、month 等,需要是 dim_date 表中的字段。

对比结果

Cube 类型Cuboid 数量构建时间存储大小
普通维度更多更长更大
衍生维度明显更少更短更小

膨胀率高的原因

  1. 维度数量多,未做 Cuboid 剪枝
  2. 存在高基数维度(如用户ID、订单ID)
  3. 存在占用空间大的度量(如 Count Distinct)

错误速查

症状根因定位修复
膨胀率 > 1000%Cuboid 过多/高基数维度/重度 Count Distinct检查 GUI 体积与膨胀率;使用 StatsReader 查看体积/行数分布;禁用不命中/近似 Cuboid
构建极慢/失败维度组合爆炸/资源与切分不匹配查看构建 Job 日志;Segment 大小与 Mapper/Reducer 数强剪枝
StatsReader 无输出工具类路径与版本不匹配在 $KYLIN_HOME 执行;校验发行包中的类名
查询变慢(启用 Derived 后)查询端二次聚合成本上升查看查询计划/Profile;高频维度改回普通维度
某些 Cuboid 从不命中设计与查询模式不符查看查询日志/命中统计;在 Cube 设计中禁用该组合