实时经营看板落地:用华为云 DLI + DLV 搭建分钟级数据分析链路
【摘要】 摘要:老板要看昨天的销售额,财务要等 T+1 报表,运营想知道此刻哪个 SKU 正在爆——传统离线数仓 T+1 出数已经撑不住业务节奏。本文以连锁零售“实时经营看板”为场景,基于华为云数据湖探索 DLI 做流式 SQL 计算、数据可视化 DLV 做前端渲染,打通从业务库 CDC 采集到分钟级大屏的全链路,给出可直接照抄的建表语句、流式作业配置和看板布局方案。一、背景与痛点连锁零售 200 家...
摘要:老板要看昨天的销售额,财务要等 T+1 报表,运营想知道此刻哪个 SKU 正在爆——传统离线数仓 T+1 出数已经撑不住业务节奏。本文以连锁零售“实时经营看板”为场景,基于华为云数据湖探索 DLI 做流式 SQL 计算、数据可视化 DLV 做前端渲染,打通从业务库 CDC 采集到分钟级大屏的全链路,给出可直接照抄的建表语句、流式作业配置和看板布局方案。
一、背景与痛点
连锁零售 200 家门店,订单库在 RDS MySQL,原来出数链路是这样的:
- 凌晨 2 点 DataArts 调度跑 ETL
- 抽数到 OBS 落 Parquet
- Hive 跑汇总 SQL,约 40 分钟
- 早上 8 点财务打开 Excel 报表
问题摆在明面上:
- T+1 太慢:大促当天老板问“现在卖了多少”,没人答得上来
- 门店调价看不到效果:上午调价,下午才知道有没有用
- 库存预警滞后:热销 SKU 断货两天才发现
- 看板靠 Excel:数据口径每次都不一样,财务和业务打架
- 扩容麻烦:月底结账那几天 Hive 队列堵死
核心诉求:订单落库 1 分钟内进看板、SQL 口径统一、大屏能自助拖拽、计算资源按需弹。
二、方案设计
2.1 为什么选 DLI + DLV
|
维度
|
Hive + Tableau
|
DLI + DLV
|
|---|---|---|
|
数据时延
|
T+1 或小时级
|
分钟级 / 秒级
|
|
计算资源
|
固定集群
|
按查询量计费,闲时几乎零成本
|
|
SQL 引擎
|
MapReduce/Tez
|
Spark 原生,交互查询快
|
|
流式支持
|
需额外搭 Kafka+Storm
|
原生支持 Kafka 源表
|
|
看板对接
|
第三方 BI License
|
DLV 内置,直接连 DLI
|
|
运维
|
集群调优重
|
全托管
|
结论:查询并发不高但要快、要流式、要省钱的场景,DLI 的按量付费 + 原生流批一体最合适。如果每天要跑 PB 级批处理,还是回 DataArts + MRS。
2.2 整体架构
业务侧
├── 200 家门店 POS → RDS MySQL(订单库)
├── 小程序订单 → RDS MySQL
└── 库存系统 → RDS MySQL
│
▼ CDC 实时捕获
数据接入
├── DataArts Studio CDM(或 Kafka + Debezium)
└── 写入 Kafka topic: retail_cdc
│
▼
实时计算(DLI)
├── 源表:Kafka 流表 orders_stream
├── 维表:RDS 商品维 / 门店维(DLI 跨源)
├── 流作业 1:1 分钟窗口聚合 GMV / 订单量
├── 流作业 2:SKU 销量 TopN
└── 结果写入 DLI 表 dws_realtime
│
▼
可视化(DLV)
├── 实时 GMV 大屏
├── 门店热力地图
├── SKU 爆款榜
└── 库存预警列表
2.3 分层建模
沿用经典数仓分层,但压缩到 DLI 里跑:
- ODS:Kafka 流表,原始 CDC 事件
- DWD:明细宽表,清洗去重后的订单粒度
- DWS:1 分钟窗口聚合结果(GMV、订单数、客单价)
- ADS:DLV 直接查的应用表,字段命名面向看板
三、实操步骤
3.1 打通 CDC 采集
用 DataArts Studio 的 CDM 或自建 Debezium 都行,这里走 CDM 更省事:
- DataArts 控制台 → 数据集成 CDM → 新建集群(1 个 micro 规格够用)
- 新建连接:
- 源端:RDS MySQL(填 VPC 内地址、账号、开启 binlog 的库)
- 目的端:Kafka(华为云 DMS Kafka 实例)
- 新建作业:实时同步 → 选表
t_order、t_order_item、t_sku - 同步类型勾 增量(CDC),起始位点选“当前时间”
- 目标 topic 命名为
retail_cdc,分区数 12(按门店 ID hash)
避坑:MySQL 必须开binlog_format=ROW,且同步账号要有REPLICATION SLAVE, REPLICATION CLIENT权限,否则 CDM 起不来增量。
3.2 DLI 建库建表
库:
CREATE DATABASE IF NOT EXISTS retail_dw
WITH (LOCATION = 'obs://retail-dw/')
COMMENT '零售实时数仓';
Kafka 流表(ODS 层):
CREATE TABLE IF NOT EXISTS retail_dw.ods_orders_stream (
order_id STRING,
store_id INT,
sku_id STRING,
qty INT,
amount DECIMAL(18,2),
pay_time TIMESTAMP,
op_type STRING, -- c/u/d 来自 CDC
event_time TIMESTAMP,
WATERMARK FOR event_time AS event_time - INTERVAL '30' SECOND
) WITH (
'connector' = 'kafka',
'kafka.bootstrap.servers' = '10.0.0.11:9092,10.0.0.12:9092',
'topic' = 'retail_cdc',
'kafka.group.id' = 'dli-retail-ods',
'scan.startup.mode' = 'latest-offset',
'format' = 'json'
);
维表(跨源查 RDS):
CREATE TABLE IF NOT EXISTS retail_dw.dim_sku (
sku_id STRING,
sku_name STRING,
category STRING,
price DECIMAL(18,2)
) WITH (
'connector' = 'rds',
'url' = 'jdbc:mysql://10.0.1.20:3306/retail',
'table_name' = 't_sku',
'user_name' = '${secret:rds_user}',
'password' = '${secret:rds_pwd}'
);
账号密码走 DLI 的凭证管理${secret:xxx},别硬编码在 SQL 里,审计过不了。
聚合结果表(DWS 层):
CREATE TABLE IF NOT EXISTS retail_dw.dws_gmv_1min (
window_start TIMESTAMP,
window_end TIMESTAMP,
store_id INT,
order_cnt BIGINT,
gmv DECIMAL(18,2)
) WITH (
'connector' = 'dli',
'format' = 'parquet'
);
3.3 提交流式作业
DLI 控制台 → 作业管理 → 新建流作业(Flink 引擎):
INSERT INTO retail_dw.dws_gmv_1min
SELECT
TUMBLE_START(event_time, INTERVAL '1' MINUTE) AS window_start,
TUMBLE_END(event_time, INTERVAL '1' MINUTE) AS window_end,
store_id,
COUNT(DISTINCT order_id) AS order_cnt,
SUM(amount) AS gmv
FROM retail_dw.ods_orders_stream
WHERE op_type IN ('c','u') -- 过滤删除事件
GROUP BY TUMBLE(event_time, INTERVAL '1' MINUTE), store_id;
作业配置:
- 引擎:Flink 1.15
- CU 数:4(起步,压测后再调)
- 并行度:4
- Checkpoint:60 秒,存 OBS
- 失败重启策略:fixed-delay,3 次
点“立即运行”,状态变
RUNNING 后去 Kafka 灌几条测试数据验证。TopN 爆款作业(滑动窗口 10 分钟,每 1 分钟输出):
INSERT INTO retail_dw.ads_hot_sku
SELECT window_end, sku_id, sku_name, SUM(qty) AS qty
FROM (
SELECT
TUMBLE_END(o.event_time, INTERVAL '10' MINUTE) AS window_end,
o.sku_id, d.sku_name, SUM(o.qty) AS qty,
ROW_NUMBER() OVER (
PARTITION BY TUMBLE(o.event_time, INTERVAL '10' MINUTE)
ORDER BY SUM(o.qty) DESC
) AS rn
FROM retail_dw.ods_orders_stream o
JOIN retail_dw.dim_sku FOR SYSTEM_TIME AS OF o.event_time AS d
ON o.sku_id = d.sku_id
GROUP BY TUMBLE(o.event_time, INTERVAL '10' MINUTE), o.sku_id, d.sku_name
) WHERE rn <= 20;
3.4 DLV 建大屏
- DLV 控制台 → 新建大屏
retail-realtime-board - 添加数据源 → 选 DLI,填 Region、库
retail_dw、AK/SK(用委托授权更安全) - 拖组件:
|
组件
|
数据集 SQL
|
|---|---|
|
数字翻牌器·今日 GMV
|
SELECT SUM(gmv) FROM dws_gmv_1min WHERE window_start >= CURRENT_DATE |
|
折线图·GMV 分钟趋势
|
SELECT window_start, SUM(gmv) FROM dws_gmv_1min GROUP BY window_start ORDER BY window_start |
|
地图·门店分布
|
SELECT store_id, SUM(gmv) FROM dws_gmv_1min WHERE window_end > NOW() - INTERVAL '1' HOUR GROUP BY store_id |
|
排行榜·爆款 Top20
|
SELECT sku_name, qty FROM ads_hot_sku ORDER BY window_end DESC, qty DESC LIMIT 20 |
|
表格·库存预警
|
直连库存系统视图,阈值 < 安全库存标红
|
- 全局滤镜加“门店下拉框”,联动所有图表
- 自动刷新设 30 秒
- 发布 → 生成分享链接,投到会议室大屏
技巧:DLV 的 SQL 数据集支持变量替换,${store_filter}接下拉框,比建 N 个数据集清爽得多。
3.5 权限与审计
- DLI 库表权限用 IAM 细粒度:看板账号只给
SELECTonretail_dw - DLV 数据源用委托授权,不要在前端存 AK/SK
- 开 DLI 审计日志落 LTS,谁在什么时候查了什么留痕
- 大屏分享链接加 token 有效期,外部合作方看完自动失效
四、验证结果
|
验证项
|
方法
|
结果
|
|---|---|---|
|
端到端时延
|
POS 下单 → 大屏数字变化
|
P95 42 秒
|
|
流作业稳定性
|
连续跑 7 天
|
0 次异常重启,Checkpoint 成功率 100%
|
|
查询性能
|
DLV 折线图拉近 24 小时
|
首屏 < 1.2s
|
|
成本
|
对比原 Hive 常驻集群
|
月费用降约 55%(闲时 CU 归零)
|
|
口径一致性
|
财务 T+1 报表 vs 实时累计
|
差异 < 0.3%(迟到数据补算)
|
|
并发
|
10 人同时拖大屏筛选
|
无排队,CU 自动从 4 弹到 10
|
五、生产避坑清单
❌ 常见错误
- Watermark 设太小:设 5 秒,网络一抖迟到数据全丢,GMV 对不上账 → 按业务迟到分布设 30-60 秒
- 维表不做 temporal join:直接用普通 join,商品改名后历史数据全变新名字 → 用
FOR SYSTEM_TIME AS OF - 流作业不设 Checkpoint:Flink 挂了从零开始重放,Kafka 积压炸掉 → 必开,60 秒一次落 OBS
- DLV 数据集写
SELECT *:字段一变大屏全崩 → 显式列名 - AK/SK 硬编码在 SQL 或前端:安全扫描直接红灯 → 走委托或凭证管理
- Kafka 分区数拍脑袋:分区少于 Flink 并行度,部分并行度空转 → 分区数 ≥ 并行度 × 2
- 不做幂等:CDC 重放导致 GMV 翻倍 → 用
order_id + op_type做去重或写 upsert Kafka - 大屏自动刷新 5 秒:DLI 被自己看板打挂 → 30 秒足够,热点数据加 DLV 缓存
- 删除事件不过滤:
op_type='d'的记录也进了 SUM,GMV 变负 → WHERE 里显式排除 - 跨 Region 拉维表:DLI 在北京、RDS 在上海,每条维表查询 30ms,吞吐直接腰斩 → 同 Region 同 VPC
✅ 正确姿势
- Watermark = P99 迟到时长,宁可慢一点也别丢数
- 流作业 CU 起步给够,压测后再降,别一上来 1CU 卡到怀疑人生
- DWS 表按天分区,历史数据自动落冷存储省 OBS 钱
- 大屏所有 SQL 走 ADS 层应用表,不让前端直接查 DWD 明细
- 每晚跑一次对账作业:实时累计 vs T+1 离线,差异 > 0.5% 告警
- 流作业加监控:Kafka lag、Checkpoint 时长、反压状态三指标进云监控
六、成本结构梳理
|
计费项
|
说明
|
优化建议
|
|---|---|---|
|
DLI CU
|
流作业常驻 CU + 查询按量
|
流作业 CU 固定,查询走按需队列
|
|
OBS 存储
|
中间 Parquet + Checkpoint
|
DWS 表按天分区,30 天后转低频
|
|
DMS Kafka
|
按分区数和流量
|
分区数够用就行,别过度分
|
|
CDM 集群
|
按规格常驻
|
micro 规格扛 200 门店 CDC 绰绰有余
|
|
DLV
|
按大屏数 / 用户数
|
内部看板共用 1 个大屏 + 权限区分
|
对比原方案:Hive 集群 8 台常驻 ECS 月费 ≈ 1.9 万,DLI 按量 + Kafka + CDM 合计 ≈ 8.5 千,降本 55%,还顺带把时延从 T+1 干到分钟级。
七、总结与扩展
这条链路真正的价值不在“大屏好看”,而在把出数节奏从天级压到分钟级后,业务决策方式变了:
- 门店调价 → 15 分钟内看到销量曲线拐点
- 爆款断货 → 库存预警比原来早 1.5 天
- 大促指挥 → 老板自己拖大屏,不用等分析师出表
- 数据口径 → 统一在 DWS 层,财务和业务不再各算各的
三条可复用的经验:
- 流式不等于全流:明细走流、汇总走流、复杂的同环比还是留 T+1 批,混着用最省
- 看板性能瓶颈在 SQL 不在前端:ADS 层把该聚合的聚合完,DLV 只做渲染
- 成本杀手是常驻 CU:查询型作业一定走按量队列,别跟流作业抢固定资源
后续演进方向:
- 异常检测:DLI 流作业里接 UDF,GMV 同比跌 30% 自动推企微告警
- 预测看板:ModelArts 训练销量预测模型,DLV 上叠“今日预估”虚线
- 门店自助分析:给店长开 DLV 编辑权限,只看自己门店分片数据
- 批流一体回溯:需要重算历史时,同一份 SQL 切 batch 模式跑 OBS 历史分区
- 移动端适配:DLV 大屏另出一版手机布局,区域经理路上也能刷
本文为原创实时数仓实践,基于华为云 DLI、DLV、DMS Kafka、CDM 整理,操作步骤以当前控制台页面为准。文中时延与成本数据为特定环境实测,实际表现随数据量与规格浮动。转载请注明出处。
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)