实时数仓 1.0
(1) 强实时(秒级):监控报警、大屏展示、风控等实时业务
一般也不需要非常仔细地进行数据分层,数据直接通过Flink计算或者聚合之后将结果写MySQL/ES/HBASE/Druid/Kudu等,直接提供应用查询或者多维分析。
(2) 准实时(分钟级):实时报表
- ODS:各种数据首先汇聚于ODS数据接入层,再接着经过这些来源明细数据的数据清洗、过滤等操作,完成多来源同类明细数据的融合,形成面向业务主题的DWD数据明细层。
- DWD:在此基础上进行轻度的汇总操作,形成一定程度上方便查询的DWS轻度汇总层。
- DWS:最后再面向业务需求,在DWS层基础上进一步对数据进行组织进入ADS数据应用层
- ADS:业务在数据应用层的基础上支持用户画像、用户报表等业务场景。
基于Kafka Flink的实时数仓的lambda架构缺陷:
(1) Kafka无法支持海量数据存储。
(2) Kafka无法支持高效的OLAP查询。
(3) 无法复用基于离线数仓的数据管理:元数据管理、血缘、数据质量。
(4) 维护成本很高。很显然,这种架构下数据存在两份、schema不统一、 数据处理逻辑不统一;
(5) Kafka不支持update/upsert。实际场景中在DWS轻度汇聚层很多时候是需要更新的,DWD明细层到DWS轻度汇聚层一般会根据时间粒度以及维度进行一定的聚合,用于减少数据量,提升查询性能。
实时数仓 2.0
存储层面的流批一体:delta/hudi/iceberg
(1) 支持流式写入-增量拉取。流式写入其实现在基于Flink就可实现,无非是将checkpoint间隔设置短一点,比如1分钟,意味每分钟生成的文件就可写入HDFS。但是有两个问题,第一个问题是小文件很多,但这不是最关键的,第二个问题是最致命的,上游每分钟提交了很多文件到HDFS上,下游消费的Flink是不知道哪些文件是最新提交的,因此下游Flink就不知道应该去消费处理哪些文件。这个问题才是离线数仓做不到实时的最关键原因之一,离线数仓的玩法是说上游将数据全部导入完成了,告诉下游说这波数据全部导完了,你可以消费处理了。
数据湖解决了这个问题。实时数据链路处理的时候,上游Flink写入的文件进来之后,下游就可以将数据文件一致性地读走。这里强调一致性地读,就是不能多读一个文件也不能少读一个文件。上游这段时间写了多少文件,下游就要读走多少文件,叫增量拉取。
(2) 解决小文件多的问题。数据湖实现了相关合并小文件的接口,Spark/Flink上层引擎可以周期性地调用接口进行小文件合并。
(3) 支持批量以及流式的Upsert/Delete功能。批量Upsert/Delete功能主要用于离线数据修正。流式upsert场景上文介绍了,主要是流处理场景下经过窗口时间聚合之后有延迟数据到来的话会有更新的需求。这类需求是需要一个可以支持更新的存储系统的,而离线数仓做更新的话需要全量数据覆盖,这也是离线数仓做不到实时的关键原因之一,数据湖是需要解决掉这个问题的。
(4) 支持比较完整的OLAP生态。比如支持Hive/Spark/Presto/Impala等OLAP查询引擎,提供高效的多维聚合查询性能。
实时数仓 3.0
引擎的流批一体:Flink/Spark,Flink认为的流批一体的本质:流表二象性,Flink提出了动态表,将流表统一起来
(1) 流:动态表,对未来持续产生的数据持续计算,持续输出结果,乱序/更新/版本
(2) 批:静态表,对过去不再变化的数据一次结算,输出一次结果;无 乱序/更新/版本 问题
- 更新问题:撤回
- 乱序问题:流内
- 版本问题:流间
1 Flink的流批一体的语义使得我们可以像查询批处理中的静态表一样查询动态表
2 Flink是以流式的动态表去理解相对静止的静态表,这也是Flink从它的根本的流式世界观去理解其他事物的一种体现
3 查询动态表将生成一个连续查询。一个连续查询永远不会终止,结果也会生成一个动态表。查询不断更新其结果表,以动态反映其输入表上的更改。
最终达到 数据集成、计算、存储、查询(SQL) 统一 (流批一体、湖仓一体)