第4章 实时数仓分层设计:ODS/DWD/DWS/ADS各层职责与SQL示例
本章导入:实时数仓分层是面试高频题,核心考察对数据流转、异构存储、时效性权衡的理解。面试官期望你能清晰说出每层作用、典型存储引擎及常见ETL写法。
🎯 面试问题1:实时数仓为什么要分层?各层作用是什么?
面试官考察点:是否理解分层目的(解耦、复用、运维)以及各层在实时场景下的具体差异。
回答框架:
- 总述分层核心价值:降低耦合、提升复用、便于问题定位。
- 逐层简述ODS/DWD/DWS/ADS的职责与典型存储。
- 强调实时区别于离线:Kafka作为ODS、状态存储、窗口计算等。
示例回答(75字):
实时数仓分层借鉴离线思想,但底层用Kafka做ODS;DWD做业务清洗与Join;DWS做窗口预聚合降维;ADS直接输出指标。分层使各层独立扩展,降低流计算复杂度,也便于回溯和重跑。
可能追问:
- 如果ODS直接给应用查询会有什么问题?
- Kafka作为ODS如何保证数据不丢?
- DWD层常见的清洗规则有哪些?
⚠️ 避坑提醒:不要只说离线分层,一定要突出实时流的特殊性(如消息回溯、多流Join状态),避免与离线回答雷同。
🎯 面试问题2:请给出ODS层到DWD层的一个SQL/代码示例。
面试官考察点:是否掌握Flink SQL中源表定义、水位线设置、简单ETL以及写入Kafka sink。
回答框架:
- 先说明ODS层数据源(Kafka主题),DWD层目标(另一个Kafka主题或HBase)。
- 给出CREATE TABLE语句,加上水位线声明。
- 展示INSERT INTO DWD的SQL,包含过滤、类型转换、时间提取。
示例回答(95字):
ODS层建表:“CREATE TABLE ods_log (uid STRING, action STRING, ts BIGINT) WITH (‘connector’=‘kafka’,‘topic’=‘ods’...);” 定义水位线后,插入DWD层:“INSERT INTO dwd_user_action SELECT uid, action, TO_TIMESTAMP(FROM_UNIXTIME(ts/1000)) AS action_time FROM ods_log WHERE action IS NOT NULL;”。
可能追问:
- 水位线设置对延迟数据如何处理?
- DWD层数据如何存储?为什么不用Kafka?
- 遇到乱序数据怎么优化?
⚠️ 避坑提醒:不要只写简单SELECT,要体现实时敏感点(水位线、时间属性),并注意SQL的标准写法与Flink方言差异。
🎯 面试问题3:DWS层如何设计?举例一个实时UV的SQL。
面试官考察点:窗口聚合、去重方案、状态管理和结果存储(Kafka/Redis/ClickHouse)。
回答框架:
- 说明DWS层目标是轻度汇总,减少重复计算。
- 选择窗口(滚动/滑动)以及去重方法(HyperLogLog或BloomFilter)。
- 展示带窗口函数的SQL,并说明输出到哪一层。
示例回答(80字):
DWS层UV可用1分钟滚动窗口SQL:“SELECT window_start, COUNT(DISTINCT uid) AS uv FROM TABLE (TUMBLE(TABLE dwd_action, DESCRIPTOR(action_time), INTERVAL '1' MINUTE)) GROUP BY window_start;” 去重可配合HyperLogLog优化,结果写入ADS层或直接入ClickHouse。
可能追问:
- COUNT DISTINCT在实时场景的性能问题如何解决?
- 如果要求精确去重且数据量极大,怎么办?(RoaringBitmap)
- DWS层数据是否需要数据湖存储?
⚠️ 避坑提醒:不要忽略Flink SQL中窗口的watermark特性;面试官常追问精确去重方案,准备一两种常用算法。
📍 项目案例:电商实时UV & PV 看板(大促场景)
| 项目名称 | 电商大促实时用户行为看板 |
| 业务背景 | 双11大促期间需秒级监控各活动页PV/UV、独立访客趋势,运营侧实时调控资源位。 |
| 规模指标 | 峰值QPS 300w+,日增量80亿条行为日志;Kafka 30分区,Flink资源150CU。 |
| 技术栈 | Flink 1.14 + Kafka 2.8 + ClickHouse + Redis (去重BloomFilter) + Prometheus |
| 核心难点 | 大促数据倾斜(热点商品)、精确去重受状态膨胀影响、窗口延迟数据补偿。 |
| 面试高频追问 | ①数据倾斜怎么定位和解决?(Local Key+二次聚合)②BloomFilter误判率如何控制?③双流Join延迟怎么优化? |
| 可迁移回答话术 | “我们采用两阶段聚合+随机前缀打散热点Key;BloomFilter大小设为预估UV的10倍容量,误判率控制在0.01%以下;遇到迟到的Join事件,使用旁路流+定时器做异步补偿。” |
📌 结构化面试提示:回答项目时先讲背景和规模(引起重视),再讲技术方案(突出分层设计),最后落到量化效果(延迟由1min降至5s)。面试官喜欢STAR结构。