**说明:**本规范可作为电商/跨境电商实时数仓开发规范参考。
版本记录
| 版本 | 日期 | 修订人 | 修订内容 |
|---|---|---|---|
| v1.0 | 2026-04-05 | 数据架构组 | 初始版本发布 |
一、总则
1.1 适用范围
本规范适用于基于 阿里云 SelectDB(StarRocks) + Flink CDC + Kafka + Apache Paimon 架构的电商实时数仓开发。所有实时数据链路的设计、开发、上线、运维均须遵守本规范。
1.2 核心原则
-
分层解耦:遵循 ODS → DWD → DWS → ADS 经典分层,层与层之间通过 Kafka Topic 或 Paimon 表解耦。
-
数据一致性优先:端到端保证 Exactly-Once 语义,状态 TTL 必设,主键模型必定义。
-
命名即文档:库、表、字段、Topic 命名统一规范,见名知意。
-
变更可控:Schema 变更需走审批流程,DDL 操作须在测试环境验证。
-
可观测性:每条链路必须接入监控告警,关键指标需配置阈值。
二、架构分层与数据流向
2.1 分层架构图
┌─────────────────────────────────────────────────────────────┐
│ ADS 层 (Application Data Service) │
│ - StarRocks / SelectDB 聚合表 │
│ - 面向大屏、API、报表 │
└─────────────────────────────────────────────────────────────┘
▲
│ Flink SQL 流式聚合 / 物化视图
│
┌─────────────────────────────────────────────────────────────┐
│ DWS 层 (Data Warehouse Service) │
│ - Paimon 轻度汇总表 │
│ - 分钟/小时级窗口聚合 │
└─────────────────────────────────────────────────────────────┘
▲
│ Flink SQL 窗口聚合 / Join
│
┌─────────────────────────────────────────────────────────────┐
│ DWD 层 (Data Warehouse Detail) │
│ - Paimon 主键表(明细宽表) │
│ - 清洗、去重、维表关联 │
└─────────────────────────────────────────────────────────────┘
▲
│ Flink SQL 清洗 / 维表 Join
│
┌─────────────────────────────────────────────────────────────┐
│ ODS 层 (Operational Data Store) │
│ - Kafka Topic (原始 CDC 数据) │
│ - Paimon Append-Only 表(可选,用于数据归档) │
└─────────────────────────────────────────────────────────────┘
▲
│ Flink CDC / Kafka Connect
│
┌─────────────────────────────────────────────────────────────┐
│ 业务数据源 (Source) │
│ - MySQL (订单、用户、商品) │
│ - 用户行为日志 (Nginx / SDK) │
└─────────────────────────────────────────────────────────────┘
2.2 数据流向规范
| 流向 | 技术组件 | 一致性保证 | 延迟要求 |
|---|---|---|---|
| MySQL → ODS (Kafka) | Flink CDC | At-Least-Once + 幂等 | < 5s |
| ODS (Kafka) → DWD (Paimon) | Flink SQL | Exactly-Once | < 30s |
| DWD (Paimon) → DWS (Paimon) | Flink SQL | Exactly-Once | < 1min |
| DWS (Paimon) → ADS (SelectDB) | Flink SQL / 物化视图 | Exactly-Once | < 10s |
三、命名规范
3.1 数据库命名
| 环境 | 库前缀 | 示例 | 说明 |
|---|---|---|---|
| 生产 | prod_ |
prod_ods, prod_dwd, prod_dws, prod_ads |
生产环境专用 |
| 测试 | test_ |
test_ods, test_dwd |
测试环境,数据可随时清理 |
| 开发 | dev_ |
dev_ods |
个人开发调试,数据无保障 |
3.2 表命名
格式 :{层级前缀}_{业务域}_{表描述}_{后缀}
| 层级 | 前缀 | 示例 |
|---|---|---|
| ODS | ods_ |
ods_trade_orders, ods_log_user_behavior |
| DWD | dwd_ |
dwd_trade_order_wide, dwd_user_profile |
| DWS | dws_ |
dws_trade_shop_1min, dws_user_cumulative |
| ADS | ads_ |
ads_bi_gmv_trend, ads_api_order_status |
后缀规范:
-
快照表:
_snapshot -
增量表:
_delta -
临时表:
_tmp_{yyyymmdd} -
备份表:
_bak_{yyyymmdd}
3.3 字段命名
-
全部采用 小写字母 + 下划线 风格。
-
布尔类型字段以
is_开头:is_deleted,is_valid。 -
时间字段统一后缀:
-
日期:
_date(DATE 类型) -
时间戳:
_time(TIMESTAMP/DATETIME 类型)
-
-
金额字段统一后缀
_amount,类型为DECIMAL(20,2)。 -
主键字段必须包含在表定义中,且命名清晰:
order_id,user_id。
3.4 Kafka Topic 命名
格式 :{业务域}.{层级}.{表名}
| 示例 | 说明 |
|---|---|
ecommerce.ods.orders |
电商域 ODS 层订单原始 CDC 数据 |
ecommerce.dwd.order_wide |
电商域 DWD 层订单宽表变更流 |
log.ods.user_behavior |
日志域用户行为原始数据 |
四、数据模型设计规范
4.1 Paimon 表设计规范
4.1.1 表类型选择
| 数据特征 | 表类型 | 必须配置 |
|---|---|---|
| CDC 同步、有 Upsert/Delete | 主键表 | PRIMARY KEY, merge-engine, changelog-producer |
| 日志、埋点等不可变数据 | Append-Only 表 | 无主键,按时间分区 |
| 需要 Time Travel 的历史快照 | 主键表 + 标签 | snapshot.time-retained |
4.1.2 主键表必设参数
WITH (
'bucket' = '{N}', -- 必填,且创建后不可修改
'merge-engine' = 'deduplicate', -- 去重
'changelog-producer' = 'input', -- CDC 源必设为 input
'snapshot.time-retained' = '7 d', -- 快照保留 7 天
'file.format' = 'parquet',
'file.compression' = 'zstd'
);
4.1.3 分桶数(bucket)设置公式
bucket = max(下游消费并行度, 预计单日数据量(GB) / 5)
-
最小值:4
-
最大值:128(超过需走审批)
-
警告 :
bucket一旦设定,无法修改。
4.1.4 分区规范
-
必须 按时间字段分区,分区字段统一命名为
dt(格式yyyy-MM-dd)或hour(格式yyyy-MM-dd HH)。 -
分区字段从业务时间字段派生:
dt AS DATE_FORMAT(order_time, 'yyyy-MM-dd')
4.2 SelectDB 表设计规范
4.2.1 模型选择决策树
是否需要有 Upsert/Delete 操作?
├── 是 → 是否有聚合需求?
│ ├── 是 → AGGREGATE KEY 模型
│ └── 否 → UNIQUE KEY 模型
└── 否 → DUPLICATE KEY 模型
4.2.2 Unique 模型写时合并 vs 读时合并
| 场景 | 推荐配置 | 理由 |
|---|---|---|
| 高频写入(>10万行/s) | enable_unique_key_merge_on_write = false |
写入性能优先 |
| 高频点查(API 服务) | enable_unique_key_merge_on_write = true |
查询性能优先 |
4.2.3 分区分桶规范
| 配置项 | 规范 | 示例 |
|---|---|---|
| 分区字段 | 必须使用动态分区,时间单位按需(DAY/HOUR) | PARTITION BY RANGE(create_time) () |
| 分桶字段 | 选择高基数、分布均匀的字段(如主键) | DISTRIBUTED BY HASH(order_id) |
| 分桶数 | 建议为 BE 节点 CPU 总数的 2~4 倍 | 3节点 × 16核 → 96 ~ 192 桶 |
五、数据接入规范
5.1 Flink CDC 接入规范
5.1.1 MySQL 源表必设参数
WITH (
'connector' = 'mysql-cdc',
'scan.startup.mode' = 'initial', -- 全量+增量,生产必选
'debezium.snapshot.locking.mode' = 'none', -- 无锁快照,避免锁表
'server-time-zone' = 'Asia/Shanghai',
'debezium.event.deserialization.failure.handling.mode' = 'warn'
);
5.1.2 大表全量同步注意事项
-
全量阶段预估耗时 > 1 小时,需提前通知 DBA。
-
全量阶段 Checkpoint 间隔调大至 10 分钟,避免频繁快照影响性能。
-
全量完成后,务必验证增量续接成功,观察 Binlog Offset 是否推进。
5.2 Kafka Sink 规范
WITH (
'connector' = 'upsert-kafka',
'sink.delivery-guarantee' = 'exactly_once',
'sink.transactional-id-prefix' = 'flink-txn-{job_name}-',
'properties.compression.type' = 'lz4'
);
5.3 SelectDB Sink 规范
WITH (
'connector' = 'doris',
'sink.properties.format' = 'json',
'sink.properties.strip_outer_array' = 'true', -- 必开,批量写入优化
'sink.enable-delete' = 'true', -- CDC 同步必开
'sink.buffer-flush.max-rows' = '50000', -- 攒批行数
'sink.buffer-flush.interval' = '5s', -- 攒批间隔
'sink.max-retries' = '3'
);
六、Flink SQL 开发规范
6.1 作业参数必设项
-- 状态与 Checkpoint
SET 'execution.checkpointing.interval' = '3min';
SET 'execution.checkpointing.mode' = 'EXACTLY_ONCE';
SET 'state.backend' = 'rocksdb';
SET 'state.backend.incremental' = 'true';
SET 'table.exec.state.ttl' = '86400000'; -- 1 天,必须设置
-- 性能优化
SET 'table.exec.mini-batch.enabled' = 'true';
SET 'table.exec.mini-batch.allow-latency' = '5s';
SET 'table.exec.mini-batch.size' = '20000';
6.2 维表 Join 规范
强制要求:Lookup Join 必须配置缓存且开启异步。
WITH (
'lookup.cache.max-rows' = '100000',
'lookup.cache.ttl' = '10min',
'lookup.async' = 'true'
);
6.3 窗口聚合规范
-
必须使用 Window TVF 语法(
TUMBLE/HOP/CUMULATE),禁止使用已废弃的 Group Window。 -
水位线延迟设置:
-
普通业务:
INTERVAL '5' SECOND -
允许较大延迟的业务:
INTERVAL '30' SECOND
-
-- 正确示例
SELECT window_start, window_end, shop_id, SUM(amount)
FROM TABLE(
TUMBLE(TABLE orders, DESCRIPTOR(order_time), INTERVAL '1' MINUTE)
)
GROUP BY window_start, window_end, shop_id;
6.4 去重规范
-
对于 Kafka 源可能产生的重复数据,使用
ROW_NUMBER()按主键去重。 -
去重窗口保留时间由
table.exec.state.ttl控制。
INSERT INTO dwd_table
SELECT order_id, ...
FROM (
SELECT *, ROW_NUMBER() OVER (
PARTITION BY order_id ORDER BY update_time DESC
) AS rn
FROM kafka_source
) WHERE rn = 1;
七、运维监控规范
7.1 必监控指标
| 指标分类 | 指标名称 | 告警阈值 |
|---|---|---|
| Flink 作业 | Checkpoint 失败次数 | > 0 |
| Flink 作业 | 端到端 Checkpoint 耗时 | > 5min |
| Flink 作业 | Kafka Source Lag | > 100万 或 > 30min |
| SelectDB | 查询失败率 | > 1% |
| SelectDB | 导入任务失败数 | > 0 |
| SelectDB | BE 节点 CPU 使用率 | > 80% |
| Paimon | 快照过期失败 | > 0 |
| Paimon | Compaction 队列积压 | > 1000 |
7.2 告警响应流程
-
P0 级告警(作业失败、数据停止产出):
-
5 分钟内响应,15 分钟内定位原因。
-
优先从 Savepoint 恢复,禁止无状态重启。
-
-
P1 级告警(Lag 上涨、延迟超阈值):
-
30 分钟内响应,2 小时内解决。
-
常见处理:增加并行度、优化 Sink 吞吐。
-
-
P2 级告警(资源使用率偏高):
- 当日评估是否需要扩容,纳入迭代计划。
7.3 数据质量校验
每个 DWD 层作业必须输出以下数据质量指标:
-- 示例:监控订单金额为空的占比
INSERT INTO quality_metrics
SELECT
'dwd_order_wide' AS table_name,
'null_amount_ratio' AS metric_name,
CAST(SUM(CASE WHEN amount IS NULL THEN 1 ELSE 0 END) AS DOUBLE) / COUNT(*) AS value,
CURRENT_TIMESTAMP AS ts
FROM dwd_order_wide;
八、变更管理规范
8.1 Schema 变更流程
| 变更类型 | 操作步骤 | 风险等级 |
|---|---|---|
| 增加非主键列 | 1. SelectDB/Paimon ALTER TABLE ADD COLUMN 2. 更新 Flink 作业 DDL,从 Savepoint 恢复 |
低 |
| 删除列 | 1. 确认列无下游依赖 2. 先修改作业逻辑停止写入该列 3. 再 ALTER TABLE DROP COLUMN |
中 |
| 修改列类型 | 禁止操作。必须新建表 + 数据迁移。 | 高 |
| 修改主键 | 禁止操作。必须重建表。 | 高 |
8.2 作业变更流程
-
开发环境验证:SQL 语法校验 + 本地 MiniCluster 测试。
-
测试环境验证:模拟生产数据量压测,观察 Checkpoint 和状态大小。
-
生产上线:
-
新作业:直接启动。
-
修改作业:必须从最新 Savepoint 恢复,禁止无状态启动。
-
-
回滚预案:保留上线前 Savepoint 至少 7 天。
九、安全规范
9.1 账号权限
-
生产环境 Flink 作业使用独立的只读 MySQL 账号 和读写 SelectDB 账号。
-
禁止使用
root或admin账号运行生产作业。 -
所有密码必须存储在密钥管理服务中,禁止明文写入 SQL。
9.2 数据脱敏
-
涉及手机号、身份证、邮箱等敏感字段,在 DWD 层必须脱敏。
-
脱敏函数示例:
-- 手机号脱敏:138****5678 CONCAT(SUBSTR(phone, 1, 3), '****', SUBSTR(phone, -4))
十、附录
10.1 开发检查清单
上线前必须逐项确认:
-
表命名是否符合规范?
-
Paimon 表
bucket是否合理设定? -
是否设置了
table.exec.state.ttl? -
Lookup Join 是否开启了异步和缓存?
-
Checkpoint 配置是否正确(间隔、超时、增量)?
-
是否配置了监控告警?
-
是否进行了数据量压测?
-
是否准备了回滚 Savepoint?
10.2 常用运维命令
-- 查看 Paimon 表快照
SELECT * FROM {table}$snapshots ORDER BY snapshot_id DESC LIMIT 10;
-- 手动触发 Paimon 快照过期
CALL sys.expire_snapshots('{database}.{table}', '7d');
-- 查看 SelectDB 导入任务
SHOW LOAD FROM {database} ORDER BY CreateTime DESC LIMIT 20;
-- 查看 SelectDB 表 Tablet 分布
SHOW TABLET FROM {table};
本规范自发布之日起生效,相关实时数仓开发活动均须遵守。规范解释权归数据架构组所有。