大数据开发前沿技能:Lambda vs Kappa 架构、实时数仓分层设计、Flink SQL 实现、实时 GMV 计算、CDC 数据同步、生产环境案例,从 0 到 1 搭建企业级实时数仓
📌 前言
真实生产问题
问题场景:
某电商公司数据平台遇到的问题:
问题 1:T+1 数据太慢,业务等不起
- 老板早上 9 点要看昨日 GMV,但 ETL 任务 10 点才跑完
- 运营要做促销活动,需要实时监控订单量,但数据滞后 1 天
- 风控要识别刷单行为,需要秒级发现,但离线数仓做不到
问题 2:实时数据不准,不敢用
- 实时 GMV 与离线对不上,差异 5-10%
- 重启任务后,数据重复或丢失
- 乱序数据导致窗口计算结果波动
问题 3:架构复杂,维护成本高
- Lambda 架构:离线 + 实时两套代码,维护成本高
- 数据不一致:离线和实时计算结果对不上
- 开发效率低:一个需求要开发两遍
实时数仓解决:
- 时效性提升:T+1 → 秒级/分钟级
- 数据一致性:统一计算逻辑,离线实时一套代码
- 架构简化:Kappa 架构,只保留实时链路
- 业务价值:支持实时监控、实时风控、实时推荐
优化后效果:
- 数据延迟:1 天 → 3-5 秒
- 数据准确率:90% → 99.99%
- 开发效率:2 套代码 → 1 套代码
- 业务价值:支持双 11 大屏、实时风控、个性化推荐
🏗️ 实时数仓架构深度解析
Lambda 架构 vs Kappa 架构
Lambda 架构(经典但复杂)
数据源(Kafka)
│
┌───────────┴───────────┐
↓ ↓
┌───────────────┐ ┌───────────────┐
│ 实时链路 │ │ 离线链路 │
│ Flink/Spark │ │ Hive/Spark │
│ 速度快 │ │ 数据准 │
│ 可能不准 │ │ 速度慢 │
└───────┬───────┘ └───────┬───────┘
│ │
└───────────┬───────────┘
↓
┌───────────────┐
│ 服务层 │
│ 合并查询 │
└───────────────┘
优点:
✓ 实时和离线互相校验
✓ 离线数据更准确
✓ 实时链路可降级
缺点:
✗ 两套代码,维护成本高
✗ 数据一致性难保证
✗ 开发效率低(一个需求做两遍)
适用场景:
- 对数据准确性要求极高(财务数据)
- 实时链路不稳定,需要离线兜底
- 团队资源充足,能维护两套系统
Kappa 架构(推荐)⭐
数据源(Kafka)
│
↓
┌───────────────┐
│ Flink 实时 │
│ 统一计算 │
└───────┬───────┘
│
┌───────────┼───────────┐
↓ ↓ ↓
┌───────────┐ ┌───────────┐ ┌───────────┐
│ 实时数仓 │ │ 数据服务 │ │ 离线导出 │
│ Doris/ │ │ API/ │ │ Hive/ │
│ StarRocks │ │ ClickHouse│ │ 归档 │
└───────────┘ └───────────┘ └───────────┘
优点:
✓ 一套代码,维护简单
✓ 数据天然一致
✓ 开发效率高
缺点:
✗ 对实时链路稳定性要求高
✗ 历史数据回溯需要重放
适用场景:
✓ 90% 的实时数仓场景
✓ 团队资源有限
✓ 追求开发效率
对比总结:
| 特性 | Lambda 架构 | Kappa 架构 |
|---|---|---|
| 代码套数 | 2 套 | 1 套 |
| 维护成本 | 高 | 低 |
| 数据一致性 | 难保证 | 天然一致 |
| 开发效率 | 低 | 高 |
| 系统复杂度 | 高 | 低 |
| 推荐使用 | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ |
建议:优先使用 Kappa 架构,除非有明确的离线兜底需求。
实时数仓分层设计
实时数仓为什么要分层?
问题:直接把 Kafka 数据写入数据库不行吗?
答案:可以,但会有问题
问题 1:数据质量无法保证
- 源数据有错误(空值、异常值)
- 直接写入,错误传播到下游
问题 2:计算逻辑重复
- 订单 GMV 计算:A 任务算一遍,B 任务又算一遍
- 计算逻辑变更,10 个任务都要改
问题 3:数据不一致
- 同一指标,不同任务计算结果不同
- 老板问:为什么两个报表数据不一样?
解决方案:分层架构
- ODS 层:原始数据,保持原貌
- DWD 层:清洗后的明细数据
- DWS 层:轻度聚合,统一指标
- ADS 层:面向应用的指标
实时数仓分层架构:
数据源(MySQL Binlog / 日志)
↓ Kafka
↓
┌─────────────────────────────────────────┐
│ ODS 层(实时) │
│ - 保持与源数据一致 │
│ - 表:ods_order_info, ods_user_info │
│ - 技术:Flink CDC → Kafka → Paimon │
└─────────────────────────────────────────┘
↓ Flink SQL
┌─────────────────────────────────────────┐
│ DWD 层(实时) │
│ - 数据清洗、维度关联 │
│ - 表:dwd_order_info, dwd_user_info │
│ - 技术:Flink SQL → Kafka → Doris │
└─────────────────────────────────────────┘
↓ Flink SQL
┌─────────────────────────────────────────┐
│ DWS 层(实时) │
│ - 轻度聚合,统一指标 │
│ - 表:dws_gmv_1min, dws_user_order_1d │
│ - 技术:Flink SQL → Doris/StarRocks │
└─────────────────────────────────────────┘
↓
┌─────────────────────────────────────────┐
│ ADS 层(实时) │
│ - 面向具体应用 │
│ - 表:ads_gmv_screen, ads_realtime_rank│
│ - 技术:Doris/ClickHouse → 大屏/API │
└─────────────────────────────────────────┘
与离线数仓对比:
| 特性 | 离线数仓 | 实时数仓 |
|---|---|---|
| 数据延迟 | 小时/天 | 秒/分钟 |
| 存储格式 | ORC/Parquet | Doris/StarRocks |
| 计算引擎 | Hive/Spark | Flink |
| 调度方式 | 定时调度 | 持续运行 |
| 数据更新 | 批量覆盖 | 流式更新 |
| 表类型 | 静态表 | 动态表 |
🔧 Flink SQL 深度实战
Flink SQL 基础
为什么用 Flink SQL?
方案对比:
方案 1:Flink DataStream API
优点:灵活,可精细控制
缺点:代码复杂,维护成本高
代码量:500+ 行
方案 2:Flink SQL ⭐推荐
优点:简洁,易维护,声明式
缺点:复杂逻辑支持有限
代码量:50+ 行
建议:
- 简单 ETL、聚合:Flink SQL
- 复杂自定义逻辑:DataStream API
- 混合使用:SQL + UDF
环境搭建:
# Flink 配置(flink-conf.yaml)
taskmanager.memory.process.size: 4096m
jobmanager.memory.process.size: 2048m
# 状态后端配置
state.backend: rocksdb
state.checkpoints.dir: hdfs:///flink/checkpoints
state.savepoints.dir: hdfs:///flink/savepoints
# Checkpoint 配置
execution.checkpointing.interval: 60000 # 1 分钟
execution.checkpointing.mode: EXACTLY_ONCE
execution.checkpointing.timeout: 600000
execution.checkpointing.max-concurrent-checkpoints: 1
execution.checkpointing.min-pause: 30000
实时 ODS 层:Flink CDC 同步
需求:将 MySQL 订单表实时同步到 Kafka
MySQL 源表:
-- 源表:MySQL 订单表
CREATE TABLE orders (
order_id BIGINT PRIMARY KEY,
user_id BIGINT,
pay_amount DECIMAL(18,2),
order_status INT,
create_time DATETIME,
update_time DATETIME
);
-- 开启 Binlog
-- my.cnf 配置:
-- server_id=1
-- log_bin=mysql-bin
-- binlog_format=ROW
-- binlog_row_image=FULL
Flink CDC 同步任务:
-- Flink SQL 任务:MySQL → Kafka
-- 1. 创建 MySQL CDC 源表
CREATE TABLE ods_order_info_source (
order_id BIGINT,
user_id BIGINT,
pay_amount DECIMAL(18,2),
order_status INT,
create_time TIMESTAMP(3),
update_time TIMESTAMP(3),
PRIMARY KEY (order_id) NOT ENFORCED
) WITH (
'connector' = 'mysql-cdc',
'hostname' = '192.168.1.100',
'port' = '3306',
'username' = 'flink',
'password' = 'flink123',
'server-time-zone' = 'Asia/Shanghai',
'database-name' = 'ecommerce',
'table-name' = 'orders',
'scan.startup.mode' = 'initial' -- initial:全量 + 增量
);
-- 2. 创建 Kafka 输出表
CREATE TABLE ods_order_info_sink (
order_id BIGINT,
user_id BIGINT,
pay_amount DECIMAL(18,2),
order_status INT,
create_time TIMESTAMP(3),
update_time TIMESTAMP(3),
PRIMARY KEY (order_id) NOT ENFORCED
) WITH (
'connector' = 'kafka',
'topic' = 'ods_order_info',
'properties.bootstrap.servers' = 'kafka1:9092,kafka2:9092,kafka3:9092',
'properties.transaction.timeout.idle' = '15min',
'format' = 'cdc-json', -- CDC 格式,支持 update/delete
'sink.parallelism' = '4'
);
-- 3. 数据同步
INSERT INTO ods_order_info_sink
SELECT * FROM ods_order_info_source;
提交任务:
# 打包 SQL 任务
cat > sync_order.sql << EOF
-- 上面创建的表和数据同步语句
EOF
# 提交到 Flink 集群
./bin/sql-client.sh -f sync_order.sql
# 或使用 Flink CLI
./bin/flink run -d \
-c org.apache.flink.table.gateway.cli.SqlGateway \
sql-gateway.jar \
-f sync_order.sql
监控任务:
# 查看任务状态
./bin/flink list --running
# 查看 Checkpoint 状态
curl http://flink-jobmanager:8081/flink-ui/api/v1/checkpoints
# 查看任务延迟
curl http://flink-jobmanager:8081/flink-ui/api/v1/jobs/{job_id}/backpressure
实时 DWD 层:数据清洗与维度关联
需求:清洗订单数据,关联用户和商品维度
Flink SQL 任务:
-- 创建 Kafka 源表(ODS 层数据)
CREATE TABLE ods_order_info (
order_id BIGINT,
user_id BIGINT,
pay_amount DECIMAL(18,2),
order_status INT,
create_time TIMESTAMP(3),
update_time TIMESTAMP(3)
) WITH (
'connector' = 'kafka',
'topic' = 'ods_order_info',
'properties.bootstrap.servers' = 'kafka1:9092',
'format' = 'json',
'scan.startup.mode' = 'latest-offset'
);
-- 创建维度表(MySQL)
CREATE TABLE dim_user (
user_id BIGINT,
user_name STRING,
gender STRING,
city STRING,
member_level STRING
) WITH (
'connector' = 'jdbc',
'url' = 'jdbc:mysql://mysql:3306/ecommerce',
'username' = 'flink',
'password' = 'flink123',
'table-name' = 'dim_user',
'lookup.cache.max-rows' = '10000', -- 维度缓存
'lookup.cache.ttl' = '10min'
);
-- 创建 DWD 层输出表(Doris)
CREATE TABLE dwd_order_info (
order_id BIGINT,
user_id BIGINT,
user_name STRING,
gender STRING,
city STRING,
member_level STRING,
pay_amount DECIMAL(18,2),
order_status INT,
status_name STRING,
create_time TIMESTAMP(3),
dt STRING, -- 分区字段
PRIMARY KEY (order_id) NOT ENFORCED
) WITH (
'connector' = 'doris',
'fenodes' = 'doris-fe:8030',
'username' = 'root',
'password' = 'doris123',
'table.identifier' = 'ecommerce.dwd_order_info',
'sink.enable.batch-mode' = 'true',
'sink.buffer-flush.interval-ms' = '10000'
);
-- 数据清洗与维度关联
INSERT INTO dwd_order_info
SELECT
o.order_id,
o.user_id,
u.user_name,
u.gender,
u.city,
u.member_level,
o.pay_amount,
o.order_status,
CASE
WHEN o.order_status = 1 THEN '待支付'
WHEN o.order_status = 2 THEN '已支付'
WHEN o.order_status = 3 THEN '已完成'
WHEN o.order_status = 4 THEN '已取消'
ELSE '未知'
END AS status_name,
o.create_time,
DATE_FORMAT(o.create_time, 'yyyy-MM-dd') AS dt
FROM ods_order_info o
JOIN dim_user FOR SYSTEM_TIME AS OF o.create_time AS u
ON o.user_id = u.user_id
WHERE o.pay_amount > 0 -- 过滤异常值
AND o.user_id IS NOT NULL;
关键点解析:
1. 维度关联(Temporal Join)
JOIN dim_user FOR SYSTEM_TIME AS OF o.create_time
含义:关联订单创建时刻的用户维度(支持缓慢变化维)
2. 维度缓存
'lookup.cache.max-rows' = '10000'
'lookup.cache.ttl' = '10min'
作用:减少数据库查询,提高性能
3. 数据清洗
WHERE o.pay_amount > 0 AND o.user_id IS NOT NULL
作用:过滤异常数据,保证数据质量
实时 DWS 层:轻度聚合
需求:实时计算每分钟 GMV、订单数
Flink SQL 任务:
-- 创建 DWD 层源表
CREATE TABLE dwd_order_info (
order_id BIGINT,
user_id BIGINT,
city STRING,
member_level STRING,
pay_amount DECIMAL(18,2),
order_status INT,
create_time TIMESTAMP(3),
dt STRING,
WATERMARK FOR create_time AS create_time - INTERVAL '5' SECOND -- Watermark
) WITH (
'connector' = 'doris',
'fenodes' = 'doris-fe:8030',
'table.identifier' = 'ecommerce.dwd_order_info',
'scan.startup.mode' = 'latest-offset'
);
-- 创建 DWS 层输出表
CREATE TABLE dws_gmv_1min (
window_start TIMESTAMP(3),
window_end TIMESTAMP(3),
gmv DECIMAL(18,2),
order_count BIGINT,
pay_user_count BIGINT,
avg_order_value DECIMAL(18,2),
update_time TIMESTAMP(3)
) WITH (
'connector' = 'doris',
'fenodes' = 'doris-fe:8030',
'table.identifier' = 'ecommerce.dws_gmv_1min',
'sink.enable.batch-mode' = 'true'
);
-- 实时聚合(滚动窗口)
INSERT INTO dws_gmv_1min
SELECT
TUMBLE_START(create_time, INTERVAL '1' MINUTE) AS window_start,
TUMBLE_END(create_time, INTERVAL '1' MINUTE) AS window_end,
SUM(pay_amount) AS gmv,
COUNT(DISTINCT order_id) AS order_count,
COUNT(DISTINCT user_id) AS pay_user_count,
SUM(pay_amount) / COUNT(DISTINCT order_id) AS avg_order_value,
CURRENT_TIMESTAMP AS update_time
FROM dwd_order_info
WHERE order_status >= 2 -- 已支付订单
GROUP BY TUMBLE(create_time, INTERVAL '1' MINUTE);
Watermark 配置详解:
WATERMARK FOR create_time AS create_time - INTERVAL '5' SECOND
含义:
- 允许数据乱序 5 秒
- 当前最大 Event Time 为 10:00:00,则 Watermark = 09:59:55
- 当 Watermark >= 窗口结束时间,触发窗口计算
参数调优:
| 乱序程度 | 延迟设置 | 适用场景 |
|---------|---------|---------|
| 轻微(< 1 秒) | 2-3 秒 | 内网传输 |
| 中等(1-5 秒) | 5-10 秒 | 公网传输 |
| 严重(> 5 秒) | 10-30 秒 | 跨地域 |
迟到数据处理:
-- 允许迟到 10 秒(Flink DataStream API)
.window(TumblingEventTimeWindows.of(Time.minutes(1)))
.allowedLateness(Duration.ofSeconds(10))
实时 ADS 层:应用指标
需求:实时大屏 GMV、订单排行
Flink SQL 任务:
-- 创建 ADS 层输出表
CREATE TABLE ads_gmv_screen (
stat_time STRING,
gmv_total DECIMAL(18,2),
gmv_today DECIMAL(18,2),
order_count_today BIGINT,
pay_user_count_today BIGINT,
top1_city STRING,
top1_city_gmv DECIMAL(18,2),
update_time TIMESTAMP(3)
) WITH (
'connector' = 'doris',
'fenodes' = 'doris-fe:8030',
'table.identifier' = 'ecommerce.ads_gmv_screen',
'sink.enable.batch-mode' = 'true'
);
-- 实时大屏指标
INSERT INTO ads_gmv_screen
SELECT
DATE_FORMAT(CURRENT_TIMESTAMP, 'yyyy-MM-dd HH:mm:ss') AS stat_time,
(SELECT SUM(gmv) FROM dws_gmv_1min) AS gmv_total,
(SELECT SUM(gmv) FROM dws_gmv_1min
WHERE DATE_FORMAT(window_start, 'yyyy-MM-dd') = DATE_FORMAT(CURRENT_TIMESTAMP, 'yyyy-MM-dd')
) AS gmv_today,
(SELECT SUM(order_count) FROM dws_gmv_1min
WHERE DATE_FORMAT(window_start, 'yyyy-MM-dd') = DATE_FORMAT(CURRENT_TIMESTAMP, 'yyyy-MM-dd')
) AS order_count_today,
(SELECT SUM(pay_user_count) FROM dws_gmv_1min
WHERE DATE_FORMAT(window_start, 'yyyy-MM-dd') = DATE_FORMAT(CURRENT_TIMESTAMP, 'yyyy-MM-dd')
) AS pay_user_count_today,
(SELECT city FROM dwd_order_info
WHERE DATE_FORMAT(create_time, 'yyyy-MM-dd') = DATE_FORMAT(CURRENT_TIMESTAMP, 'yyyy-MM-dd')
GROUP BY city ORDER BY SUM(pay_amount) DESC LIMIT 1
) AS top1_city,
(SELECT SUM(pay_amount) FROM dwd_order_info
WHERE DATE_FORMAT(create_time, 'yyyy-MM-dd') = DATE_FORMAT(CURRENT_TIMESTAMP, 'yyyy-MM-dd')
GROUP BY city ORDER BY SUM(pay_amount) DESC LIMIT 1
) AS top1_city_gmv,
CURRENT_TIMESTAMP AS update_time
FROM dws_gmv_1min;
🏭 生产环境完整案例
案例背景
公司规模:
- 日均订单:500 万单
- 峰值 QPS:10 万+/秒
- 数据源:MySQL(订单/用户/商品)+ 日志(点击/浏览)
需求:
1. 实时 GMV 大屏(秒级更新)
2. 实时订单排行(分钟级更新)
3. 实时用户画像(小时级更新)
4. 实时风控(秒级预警)
技术选型:
- 计算引擎:Flink 1.17
- 消息队列:Kafka 3.0
- 实时数仓:Doris 2.0
- 数据存储:Paimon(数据湖)
架构设计
数据流向:
MySQL Binlog ──→ Flink CDC ──→ Kafka (ODS)
↓
日志文件 ─────→ Flink Source ──→ Kafka (ODS)
↓
Flink SQL (DWD)
↓
Doris (DWD 层)
↓
Flink SQL (DWS)
↓
Doris (DWS 层)
↓
Doris (ADS 层)
↓
大屏/API/报表
表结构设计
ODS 层(Kafka):
// Topic: ods_order_info
{
"order_id": 1001,
"user_id": 5001,
"pay_amount": 100.50,
"order_status": 2,
"create_time": "2026-03-24T10:30:00",
"op_type": "INSERT" // CDC 操作类型
}
DWD 层(Doris):
CREATE TABLE dwd_order_info (
order_id BIGINT,
user_id BIGINT,
user_name STRING,
gender STRING,
city STRING,
member_level STRING,
pay_amount DECIMAL(18,2),
order_status INT,
status_name STRING,
create_time TIMESTAMP,
dt STRING
)
DUPLICATE KEY (order_id)
PARTITION BY RANGE(dt) ()
DISTRIBUTED BY HASH(order_id) BUCKETS 32
PROPERTIES (
"replication_num" = "3",
"light_schema_change" = "true"
);
DWS 层(Doris):
CREATE TABLE dws_gmv_1min (
window_start TIMESTAMP,
window_end TIMESTAMP,
gmv DECIMAL(18,2),
order_count BIGINT,
pay_user_count BIGINT,
avg_order_value DECIMAL(18,2),
update_time TIMESTAMP
)
DUPLICATE KEY (window_start)
PARTITION BY RANGE(window_start) ()
DISTRIBUTED BY HASH(window_start) BUCKETS 10
PROPERTIES (
"replication_num" = "3",
"aggregation_policy" = "AUTO"
);
性能优化
1. Checkpoint 优化
# Flink Checkpoint 配置
execution.checkpointing.interval: 60000 # 1 分钟
execution.checkpointing.mode: EXACTLY_ONCE
execution.checkpointing.timeout: 600000 # 10 分钟
execution.checkpointing.max-concurrent-checkpoints: 1
execution.checkpointing.min-pause: 30000 # 30 秒
# RocksDB 状态后端
state.backend: rocksdb
state.backend.rocksdb.memory.managed: true
state.backend.rocksdb.memory.high-prio-pool-ratio: 0.1
2. 并行度优化
-- 设置任务并行度
SET parallelism.default = 4;
-- 单个算子并行度
INSERT INTO dwd_order_info
SELECT /*+ OPTIONS('parallelism'='8') */ * FROM ods_order_info;
3. 状态优化
-- 状态 TTL(自动清理过期状态)
SELECT * FROM dwd_order_info
/*+ OPTIONS('state.ttl'='1d') */;
-- 状态后端配置
state.backend.rocksdb.memory.fixed-per-slot: 256m
⚠️ 常见坑点与解决方案
坑点 1:数据重复
问题:
任务重启后,数据重复计算
GMV 从 100 万变成 120 万,多了 20 万
原因:
- Checkpoint 未完成,Source 重放数据
- Sink 未实现幂等写入
- 窗口重复触发
解决:
-- 方案 1:使用主键表(Doris/StarRocks)
CREATE TABLE dwd_order_info (
order_id BIGINT,
...
PRIMARY KEY (order_id) NOT ENFORCED
) WITH (...);
-- 方案 2:Sink 端 UPSERT
-- Doris Connector 自动实现幂等写入
-- 方案 3:去重窗口
SELECT
window_start,
COUNT(DISTINCT order_id) AS order_count -- 去重计数
FROM dwd_order_info
GROUP BY TUMBLE(create_time, INTERVAL '1' MINUTE);
坑点 2:数据延迟
问题:
数据延迟严重,大屏显示滞后 10 分钟
原因:
- 数据倾斜:某个 Key 数据量过大
- Checkpoint 超时:状态太大,Checkpoint 时间过长
- 背压:下游处理慢,上游堆积
解决:
-- 方案 1:数据倾斜处理(加盐)
SELECT
CONCAT(order_id, '_', FLOOR(RAND() * 10)) AS salted_key,
SUM(pay_amount) AS partial_gmv
FROM dwd_order_info
GROUP BY CONCAT(order_id, '_', FLOOR(RAND() * 10));
-- 方案 2:优化 Checkpoint
execution.checkpointing.interval: 30000 -- 缩短间隔
state.backend.rocksdb.memory.managed: true
-- 方案 3:监控背压
curl http://flink-jobmanager:8081/flink-ui/api/v1/jobs/{job_id}/backpressure
坑点 3:乱序数据
问题:
窗口计算结果忽高忽低,不稳定
原因:
- 数据乱序到达
- Watermark 配置不合理
- 窗口触发过早
解决:
-- 方案 1:调整 Watermark
WATERMARK FOR create_time AS create_time - INTERVAL '10' SECOND
-- 方案 2:允许迟到
-- Flink DataStream API
.window(TumblingEventTimeWindows.of(Time.minutes(1)))
.allowedLateness(Duration.ofSeconds(10))
-- 方案 3:侧输出迟到数据
final OutputTag<Order> lateTag = new OutputTag<Order>("late-data") {};
dataStream
.window(TumblingEventTimeWindows.of(Time.minutes(1)))
.allowedLateness(Duration.ofSeconds(10))
.sideOutputLateData(lateTag);
📋 最佳实践清单
架构设计
- 优先使用 Kappa 架构(一套代码)
- 实时数仓分层(ODS/DWD/DWS/ADS)
- 统一指标口径(只在一个地方计算)
- 预留离线导出接口
开发规范
- 使用 Flink SQL(简洁易维护)
- 合理设置 Watermark(根据乱序程度)
- 开启 Checkpoint(Exactly-Once)
- 实现幂等写入(主键表/UPSERT)
性能优化
- 合理设置并行度(根据数据量)
- 使用 RocksDB 状态后端(大状态)
- 开启维度缓存(Lookup Join)
- 监控背压和延迟
监控告警
- 监控任务状态(Running/Failed)
- 监控 Checkpoint 延迟
- 监控数据延迟(Source → Sink)
- 监控数据质量(对账)
📌 总结
核心要点
| 概念 | 要点 | 推荐使用 |
|---|---|---|
| 架构选择 | Lambda vs Kappa | Kappa⭐⭐⭐⭐⭐ |
| 计算引擎 | Flink SQL vs DataStream | SQL⭐⭐⭐⭐⭐ |
| 状态后端 | Memory vs RocksDB | RocksDB(大状态) |
| 存储引擎 | Doris/StarRocks | Doris⭐⭐⭐⭐⭐ |
实践原则
1. 简单优先
Flink SQL 能解决的不用 DataStream
2. Exactly-Once
开启 Checkpoint,保证数据不重不漏
3. 监控完善
任务状态、数据延迟、数据质量
4. 持续优化
根据生产数据调整参数
下一步
完成实时数仓后:
1. 接入 BI 工具(实时大屏)
2. 开发实时 API(数据服务)
3. 建立数据质量监控(对账、告警)
4. 优化性能(并行度、Checkpoint)
💡 实时数仓是大数据发展的趋势,建议尽早掌握 Flink 技术!
👋 感谢阅读!
🔗 系列文章
- [01-SQL 窗口函数从入门到精通](./01-SQL 窗口函数从入门到精通.md)
- [02-Spark 性能优化 10 个技巧](./02-Spark 性能优化 10 个技巧.md)
- 03-数据仓库分层设计指南
- 04-维度建模实战
- 05-Flink 实时数仓实战(本文)
- [下一篇:Kafka 消息队列实战指南](./06-Kafka 消息队列实战指南.md)