订阅更新

ODS/DWD/DWS/ADS全建在Doris里?——实时数仓分层实践

Doris手册 第 10 题 约 10 分钟读完

本文目录
  1. 先说结论
  2. 实时数仓分层 vs 离线数仓分层
  3. 我在某元宇宙社交公司的实时数仓分层
  4. 每一层在Doris里用什么数据模型?
  5. Doris数仓 vs 传统Hive数仓的核心区别
  6. 实战经验:两家公司的不同分层实践对比
  7. 实战踩坑:全量数据都放Doris导致存储爆了
  8. 面试高频追问
  9. 总结

先说结论

实时数仓不是把所有层都搬到Doris里。最佳实践是:Kafka做ODS层(原始数据缓冲)、Flink做实时ETL(DWD/DWS加工)、Doris做查询层(DWD明细查询+DWS/ADS汇总查询)。大量历史数据的存储底座还是用S3/HDFS+Hive/Spark。

核心原则:Doris负责'热数据'的实时查询(最近7-30天),Hive/S3负责'冷数据'的长期存储和复杂ETL。

先把这段讲顺;面试官追问时,再展开下面的原理和细节。

详细讲解

实时数仓分层是面试的经典题目,但如果你说的分层和Hive离线数仓一模一样,面试官就会追问:实时数仓和离线数仓的分层有什么区别?所有层都建在Doris里吗?什么数据适合放Doris什么适合放Hive?我在某元宇宙社交公司搭建过Flink+Kafka+Doris的实时数仓,在某短剧出海公司用过Hologres+MaxCompute的混合架构,今天把两种实践经验对比着讲清楚。

实时数仓分层 vs 离线数仓分层

层级离线数仓(Hive)实时数仓(Doris)区别
ODSHDFS/S3原始文件Kafka Topic实时数仓ODS在Kafka里,不在Doris
DWDHive表,T+1产出Doris Duplicate表,秒级写入实时数仓DWD是秒级更新的
DWSHive聚合表,T+1产出Doris Aggregate/物化视图实时数仓DWS接近实时
ADSHive应用表/导出MySQLDoris表直接查/接口服务不需要导出,Doris自己就能服务查询
DIMHive维度表/MySQLDoris Unique表+CDC同步实时数仓维度表也是实时更新的

我在某元宇宙社交公司的实时数仓分层

# 实时数仓完整架构
#
# ┌─ ODS层(Kafka)─────────────────────────┐
# │ user_event Topic  ← 埋点SDK实时写入      │
# │ gift_txn Topic    ← FlinkCDC从MySQL同步   │
# │ user_sync Topic   ← FlinkCDC用户维度同步  │
# └────────────────────────────────────────┘
#           ↓  Flink DataStream消费+ETL
# ┌─ DWD层(Doris Duplicate表)───────────────┐
# │ dwd_user_event  ← 清洗后的用户行为明细     │
# │ dwd_gift_txn    ← 清洗后的交易明细         │
# └────────────────────────────────────────┘
#           ↓  Doris物化视图 / Flink聚合
# ┌─ DWS层(Doris Aggregate/物化视图)────────┐
# │ dws_daily_overview  ← 每日UV/PV/GMV汇总   │
# │ mv_country_stats    ← 按国家的物化视图     │
# └────────────────────────────────────────┘
#           ↓  直接查询
# ┌─ ADS层(Doris表 / Metabase大盘)──────────┐
# │ 实时大盘(Metabase连接Doris)              │
# │ 运营后台(API查询Doris)                   │
# └────────────────────────────────────────┘
#
# ┌─ DIM层(Doris Unique表)──────────────────┐
# │ dim_user    ← FlinkCDC实时同步             │
# │ dim_gift    ← FlinkCDC实时同步             │
# └────────────────────────────────────────┘

每一层在Doris里用什么数据模型?

层级表名Doris模型原因
DWDdwd_user_eventDuplicate保留所有明细,支持多维分析
DWDdwd_gift_txnUnique按transaction_id去重,支持状态更新
DWSdws_daily_overviewAggregate按天预聚合,查询极快
DIMdim_userUnique按user_id更新最新状态
DIMdim_giftUnique按gift_id更新配置信息

Doris数仓 vs 传统Hive数仓的核心区别

① 实时性:Hive数仓是T+1(昨天的数据今天才能看),Doris数仓是秒级(数据写入后立刻可查)。这对运营和投放决策意义重大——在某短剧出海公司,投手需要5分钟内看到广告效果数据,T+1是完全不可接受的。

② DWS层的实现方式不同:Hive的DWS层需要跑Spark/Hive SQL调度任务来聚合,Doris的DWS层可以用Aggregate模型或物化视图自动完成预聚合,不需要额外的调度任务。

③ ADS层直接服务查询:Hive的ADS层数据通常要导出到MySQL才能给业务系统用,Doris本身就支持高并发查询(兼容MySQL协议),ADS层数据直接在Doris里查就行,不需要再导出。

④ 维度表实时更新:Hive的维度表是T+1更新(每天跑一次全量覆盖),Doris的Unique模型+FlinkCDC可以做到秒级更新——用户改了昵称,几秒后Doris里的dim_user就更新了。

实战经验:两家公司的不同分层实践对比

维度某元宇宙社交公司某短剧出海公司
ODSKafka(自建集群)Kafka(阿里云托管)
ETL引擎Flink DataStreamFlink + DataWorks调度
DWD/DWS存储Doris(自建)Hologres(阿里云托管)
离线存储S3MaxCompute
BI工具Metabase云厂商BI工具
数据时效秒级5分钟
数据规模日增5000万条日增数亿条

两家公司架构思路一样,只是技术栈不同(自建 vs 云服务)。核心分层逻辑完全一致:Kafka做缓冲→Flink做ETL→OLAP引擎做查询→BI展示。

实战踩坑:全量数据都放Doris导致存储爆了

在某元宇宙社交公司刚搭实时数仓时,我把所有历史数据(半年的用户行为明细,约500GB)都导入了Doris。结果3个BE节点的2TB SSD磁盘占了70%,而且越来越多。

问题:Doris用本地SSD存储,成本远高于S3/HDFS。半年的历史数据大部分是冷数据(很少被查询),放在Doris里纯粹浪费昂贵的SSD空间。

解决方案:Doris只保留最近30天的热数据(用动态分区自动删除30天前的分区),历史数据存在S3上。需要查历史数据时用Spark读S3,或者用Doris的Multi-Catalog功能直接查S3上的Parquet文件(查询速度比本地慢但能查到)。

-- 动态分区:自动保留30天数据
ALTER TABLE dwd_user_event SET (
    'dynamic_partition.enable' = 'true',
    'dynamic_partition.time_unit' = 'DAY',
    'dynamic_partition.start' = '-30',   -- 只保留30天
    'dynamic_partition.end' = '3',
    'dynamic_partition.prefix' = 'p',
    'dynamic_partition.buckets' = '16'
);
 
-- Doris Multi-Catalog查询S3上的历史数据(Doris 2.0+)
CREATE CATALOG s3_catalog PROPERTIES (
    'type' = 'hms',
    'hive.metastore.uris' = 'thrift://hms-host:9083'
);
-- 直接查S3上的Hive/Parquet表
SELECT * FROM s3_catalog.mydb.user_event_history
WHERE dt = '2023-06-15';

教训:Doris不是万能的存储引擎。热数据放Doris(SSD高速查询),冷数据放S3/HDFS(低成本存储),用Doris的Multi-Catalog打通冷热数据查询。这才是成本和性能的最优平衡。

面试高频追问

追问一:实时数仓还需要离线数仓吗?

需要。实时数仓和离线数仓互补而非替代。实时数仓解决'快'的问题(秒级/分钟级),离线数仓解决'全'和'准'的问题(全量历史数据、复杂ETL、数据回刷)。我在元宇宙社交公司是实时数仓(Doris)和离线数仓(S3+Spark)并存的。

追问二:Doris能替代Hive做数仓底座吗?

TB级别可以,PB级别不行。Doris的存储成本比Hive高(SSD vs HDFS/S3),而且Doris不太适合做超大规模的ETL计算(MPP对复杂ETL不如Spark灵活)。最佳实践是Doris做查询加速层,Hive做存储底座。

追问三:DWS层用物化视图还是建独立的Aggregate表?

简单聚合用物化视图(自动维护,省心),复杂ETL用独立的Aggregate表+Flink/调度任务。我的经验是:能用物化视图搞定的就不建独立表,减少维护成本。但涉及多表JOIN的复杂聚合,物化视图搞不定,就要建独立的DWS表。

总结

实时数仓分层面试讲清楚三点:① 和离线数仓的区别(ODS在Kafka不在HDFS、DWS可以用物化视图自动预聚合、ADS直接查Doris不用导出MySQL);② 每层用什么Doris数据模型(DWD用Duplicate/Unique、DWS用Aggregate/物化视图、DIM用Unique);③ 冷热分离(Doris存热数据30天、S3/HDFS存冷数据、Multi-Catalog打通查询)。能结合两家公司的对比经验讲,面试官会觉得你对实时数仓有深度理解。

下一篇聊Doris的查询优化实战:慢查询怎么排查?EXPLAIN怎么看?常见的优化套路有哪些?

你们的实时数仓分层是什么样的?所有层都在Doris里吗?评论区聊聊~

关注「Wood聊大数据」| 9年大数据老兵,聊技术、聊职场、聊成长

Doris 面试通关手册

第11-15篇:运维调优与安全治理

Wood聊大数据

9年大数据老兵,聊技术、聊职场、聊成长

刷题进度保存在当前浏览器