第4章 实时数仓分层设计:ODS/DWD/DWS/ADS各层职责与SQL示例

本章导入:实时数仓分层是面试高频题,核心考察对数据流转、异构存储、时效性权衡的理解。面试官期望你能清晰说出每层作用、典型存储引擎及常见ETL写法。

1. 总体分层思想 2. ODS 数据接入 3. DWD 明细层 4. DWS 汇总层 5. ADS 应用层 Kafka / Pulsar 明细清洗 + Join 预聚合 / 宽表 OLAP / 指标输出

🎯 面试问题1:实时数仓为什么要分层?各层作用是什么?

面试官考察点:是否理解分层目的(解耦、复用、运维)以及各层在实时场景下的具体差异。

回答框架:

  1. 总述分层核心价值:降低耦合、提升复用、便于问题定位。
  2. 逐层简述ODS/DWD/DWS/ADS的职责与典型存储。
  3. 强调实时区别于离线:Kafka作为ODS、状态存储、窗口计算等。

示例回答(75字):

实时数仓分层借鉴离线思想,但底层用Kafka做ODS;DWD做业务清洗与Join;DWS做窗口预聚合降维;ADS直接输出指标。分层使各层独立扩展,降低流计算复杂度,也便于回溯和重跑。

可能追问:

  • 如果ODS直接给应用查询会有什么问题?
  • Kafka作为ODS如何保证数据不丢?
  • DWD层常见的清洗规则有哪些?

⚠️ 避坑提醒:不要只说离线分层,一定要突出实时流的特殊性(如消息回溯、多流Join状态),避免与离线回答雷同。

🎯 面试问题2:请给出ODS层到DWD层的一个SQL/代码示例。

面试官考察点:是否掌握Flink SQL中源表定义、水位线设置、简单ETL以及写入Kafka sink。

回答框架:

  1. 先说明ODS层数据源(Kafka主题),DWD层目标(另一个Kafka主题或HBase)。
  2. 给出CREATE TABLE语句,加上水位线声明。
  3. 展示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)。

回答框架:

  1. 说明DWS层目标是轻度汇总,减少重复计算。
  2. 选择窗口(滚动/滑动)以及去重方法(HyperLogLog或BloomFilter)。
  3. 展示带窗口函数的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结构。