TL;DR
- 场景: 电商销售数据多维分析,按日期/区域/产品/渠道进行 Cube 建模与预计算
- 结论: 星型建模 + Aggregation Group 剪枝可显著降低 Cuboid 数量,查询实现秒级响应
- 产出: 完整建模流程、维度设计原则、Cuboid 优化策略、错误速查表
版本矩阵
| 模块 | 技术要点 | 工程化建议 |
|---|---|---|
| 星型建模 | 事实表 + 维度表,单表 ≤300MB | 维度表主键唯一,避免 Hive 视图 |
| 维度设计 | 日期/区域/产品/渠道 | 高频维度优先,层级维度独立处理 |
| 度量设计 | SUM/COUNT/AVG/MAX/MIN | Count Distinct 需评估基数 |
| Aggregation Group | 维度分组,组合控制 | 维度 >15 建议拆分多组 |
| 必要维度 | 强制出现在 WHERE/GROUP BY | 减少无效 Cuboid |
| 层级维度 | 国家→省→市 | 仅预计算最细粒度 |
| 联合维度 | 低基数/常共同查询 | 同时出现或均不出现 |
| 构建引擎 | Hive + Spark + HBase | Spark 构建替代 MapReduce |
| 查询加速 | Cuboid 匹配 | 确保查询命中预计算结果 |
建模流程
1. 数据准备
-- 事实表:电商销售记录
CREATE TABLE fact_sales (
order_id STRING,
dt DATE COMMENT '分区字段',
region_id STRING COMMENT '区域外键',
product_id STRING COMMENT '产品外键',
channel_id STRING COMMENT '渠道外键',
amount DECIMAL(18,2) COMMENT '销售金额',
quantity INT COMMENT '销售数量'
) PARTITIONED BY (dt) STORED AS PARQUET;
-- 维度表:区域
CREATE TABLE dim_region (
region_id STRING PRIMARY KEY,
region_name STRING,
province STRING,
city STRING
) STORED AS ORC;
-- 维度表:产品
CREATE TABLE dim_product (
product_id STRING PRIMARY KEY,
product_name STRING,
category STRING,
brand STRING
) STORED AS ORC;
-- 维度表:渠道
CREATE TABLE dim_channel (
channel_id STRING PRIMARY KEY,
channel_name STRING,
channel_type STRING
) STORED AS ORC;
2. Model 定义
在 Kylin Web UI 创建 Model:
- 事实表: fact_sales
- 维度表: dim_region, dim_product, dim_channel
- 分区字段: dt(日期)
- 度量: SUM(amount), SUM(quantity), COUNT(*)
3. Cube 设计
维度配置
| 维度类型 | 字段 | 配置 |
|---|---|---|
| Mandatory | dt | 必要维度,所有查询必带 |
| Hierarchy | dim_region.province, dim_region.city | 层级维度 |
| Joint | dim_channel | 联合维度 |
| Normal | dim_product.category, dim_product.brand | 普通维度 |
Aggregation Group
Group 1: dt, region_id(高频组合) Group 2: dt, product_id(产品分析) Group 3: dt, channel_id(渠道分析)
Cube 构建
全量构建
# 通过 Kylin Web UI 或 REST API 构建
curl -X PUT --user ADMIN:KYLIN \
-H "Content-Type:application/json;charset=utf-8" \
-d '{"startTime":"","endTime":"","buildType":"BUILD"}' \
http://h122.wzk.icu:7070/kylin/api/cubes/ecommerce_cube/build
构建流程
- Step 1: Extract Fact Table - 读取 Hive 事实表
- Step 2: Build Dimension Dictionary - 构建维度字典
- Step 3: Build Cube - 计算各 Cuboid
- Step 4: Convert Cube to HBase - 转换为 HBase 存储
- Step 5: Checkpoint - 元数据落库
查询示例
SQL 查询
-- 按日期+区域统计销售额
SELECT dt, region_name, SUM(amount) AS total_amount
FROM fact_sales
JOIN dim_region ON fact_sales.region_id = dim_region.region_id
WHERE dt >= '2024-01-01' AND dt <= '2024-01-31'
GROUP BY dt, region_name;
-- 按产品类别月度汇总
SELECT SUBSTR(dt, 1, 7) AS month, category,
SUM(amount) AS total, COUNT(*) AS orders
FROM fact_sales
JOIN dim_product ON fact_sales.product_id = dim_product.product_id
GROUP BY SUBSTR(dt, 1, 7), category
ORDER BY month, total DESC;
查询命中分析
通过 Kylin Query 页面查看:
- 命中 Cuboid: 具体使用了哪个预计算的 Cuboid
- 查询时间: 是否在毫秒级完成
- 扫描行数: HBase 扫描的行数
实时 OLAP(Kafka)
Kylin 4.0 支持 Kafka 实时流接入:
- 创建 Streaming Cube: 数据源选择 Kafka
- 配置消息格式: JSON/Avro
- 设置时间窗口: 增量构建间隔(分钟级)
- 查询: 与离线 Cube 查询语法一致
{
"dimensions": {"region": "APAC", "product": "phone"},
"metrics": {"revenue": 12500, "orders": 42},
"timestamp": "2024-01-15T10:30:00Z"
}
错误速查
| 症状 | 根因定位 | 修复 |
|---|---|---|
| 构建失败,维度表主键重复 | 维度表存在重复主键 | 预处理去重,保证主键唯一 |
| 构建极慢,Cuboid 过多 | 未配置 Aggregation Group | 拆分聚合组,配置必要/层级维度 |
| 查询未命中,回源 Hive | 查询维度组合未预计算 | 补充 Cuboid 或调整查询 |
| HBase 存储膨胀 >1000% | 高基数维度 + 无剪枝 | 使用字典编码,优化维度组合 |
| 实时构建延迟高 | Kafka 消费滞后 | 调整批处理参数,增加并发 |
| 维度表内存溢出 | 维度表过大(>300MB) | 拆分维度表,减少列数 |