本系列包含:
- Doris 构建实时数仓落地方案详解(一):实时数据仓库概述
- Doris 构建实时数仓落地方案详解(二):Doris 核心功能解读
- Doris 构建实时数仓落地方案详解(三):Doris 实时数仓设计
Doris 构建实时数仓落地方案详解(三):Doris 实时数仓设计
- 1.离线数仓分层
- 2.实时数仓之 Lambda 架构
- 3.实时数仓之 Kappa 架构
- 4.基于 Doris 的流批一体方案
- 4.1 方案一
- 4.2 方案二
- 4.3 方案三
- 4.4 方案四 / 方案五
- 5.不同场景的方案选择
前面已经解读实时数仓的背景、技术线路和应用场景,这里具体从实现的角度来介绍实时数仓。
1.离线数仓分层
在介绍实时数仓之前,我们先看看离线数仓的标准架构。众所周知,离线数仓一般分为 ODS(Operational Data Store)、DW(Data Warehouse) 和 DM(Data Market) 三层架构,这里面的 ODS 就是数据接口层,目前逐步被数据湖的概念取代,但是其基本原理没有变化,主要是 数据同步方法、数据存储方式 和 增量数据获取 等方面有所加强。往上 DW 层就是数据仓库层,也是我们离线数据处理和模型设计的核心,现在通用的分层都是分为 DWD(Data Warehouse Detailed)、DIM(Dimension)、DWS(Data Warehouse Service) 三个模块,DIM 加工一致性维度;DWD 保留业务模型数据并进行数据格式规范化、字段命名标准化;DWS 聚焦指标逻辑加工,并适当进行数据汇总,减少数据量。有时候我们还会在 DWS 层的基础上增加 DWT(Data Warehouse Topic),作为宽表,但是我们也可以将这一层保留在 DWS 中,作为 DWS 层的一部分。DM 层是数据集市层,在 OLAP 查询不理想的情况下,DM 层是需要大力建设的。现在技术发展了,OLAP 查询不再是瓶颈,我们将建设的重心下移到提供一致性对外数据服务的 DWS 层,DM 层的开发工作逐步减少。
以我目前负责的电商业务为例:
- 我会在 DWD 层构建一张 订单表,整合所有接口过来的订单相关信息,包括订单的状态、收发货、业务类型、采购信息、支付信息、交易流程信息等,但是不包括商品的层级、店铺等信息。
- 在 DIM 层构建以商品为核心的 商品信息表,不仅包括商品的属性、业务分类、尺码颜色,还包括商品归属的店铺、价格、采购价等;DIM 层还有用户维度信息,包括用户的注册信息、引流信息、历史成交信息和用户画像标签等。
- 在 DWS 层,基于 DWD 层的订单信息的基础上计算成交金额、采购成本、订单折扣金额、毛利等指标。这就构成了一个简单的电商数仓最核心的订单业务流程。
2.实时数仓之 Lambda 架构
从离线数仓过渡到实时数仓,我们的基本数仓分层没有变化,只不过为了数据时效性,有时候会省掉其中一些计算步骤。
实时数仓的设计理念主要由两个思路:Lambda 架构和 Kappa 架构。
Lambda 架构是由 Twitter 工程师南森·马茨( N a t h a n M a r z Nathan\ Marz Nathan Marz)提出的。Lambda 架构简单的说就是流式数据作为批处理的补充,流数据之加工当日实时数据,批处理更新当日及之前的数据,在数据应用层将二者加工的结果合并起来。
3.实时数仓之 Kappa 架构
Kappa 架构可以认为是 Lambda 架构的简化版,即移除 Lambda 架构中的批处理部分。在 Kappa 架构中,需求变更或历史数据变化都通过上游重放完成,即回溯数据进行重算。
Lambda 架构提倡实时数据流程处理当日数据,T+1
数据用离线加工来回补和修正,具有很好的灵活性和可扩展性,也对硬件故障和人为失误有很好的容错性。由于有批处理作为后盾,实时数据加工的压力大大减轻;由于有了离线数据加工,数据的准确性也得到了保障。
Kappa 架构最大的优点是仅需一套代码,可以同时完成流式数据加工和批量数据加工,最大的问题是批量数据加工的能力会低于离线批处理,因此历时数据的回溯时长存在不确定性。
目前大部分都是采用 Lambda 架构,也有不少企业在尝试 Kappa 架构。从设计上说 Kappa 架构肯定是更优的,一套逻辑处理增量和全量,但是实际上比较难实现,或者说实现代价非常高。
要比较两种方案那种更好,我们需要先思考下面四个问题:
- 我们真的需要一个完全实时的数据仓库吗?很多业务,例如银行的日结、存款利息计算、财务报表统计等都是以日终或者月末作为时点计算的,所以并不需要实时。
- 在数据准确性和实时性之间,那个更重要?我们都知道不管是 Lambda 架构的实时部分还是 Kappa 架构架构,我们都无法做到 100 % 100\% 100% 准确的实时。
- 实时计算的中间过程数据保存在 Kafka 中,数据出现了异常,我们要怎么找原因?
- Kappa 架构虽然给我们规划了一个非常美好的蓝图,但是真的可以实现吗?
4.基于 Doris 的流批一体方案
前面我们介绍了 Doris 具备强大的 多表关联查询能力 和 基于主键的数据增删改能力。所以我们不妨结合流数据和 Doris 强大的查询能力来构建流批一体方案。简单的说就是底层逻辑用流数据写入,上层逻辑通过 SQL 关联来实现。
基于对以上四个问题的思考,我提出了基于 Doris 的全新实时数仓方案,也就是 流 + 批 组合模式。按照流数据加工的层级和批数据加工层级不同,分为了五种具体方案。
方案一 | 方案二 | 方案三 | 方案四 | 方案五 | |
---|---|---|---|---|---|
ODS | 流式写入 | 保留副本 | 保留副本 | 流式写入 | 保留副本 |
DWD | 微批加工 | FlinkSQL 写入 | 保留副本 | 视图 + 隔日刷新 | FlinkSQL 写入 |
DWS | 微批加工 | 微批加工 | FlinkSQL 写入 | 视图 + 隔日刷新 | 视图 + 隔日刷新 |
ADS | 可忽略 | 可忽略 | 可忽略 | 可忽略 | 可忽略 |
4.1 方案一
方案一是流数据写入 ODS,往上数据加工逐层进行微批处理,在保证数据准确的情况下,提高微批的频率。
我们可以通过 Flink 清洗 Kafka 日志数据写入 Doris、Doris 直接读取 MySQL Binlog、Doris 直接读取 Kafka 日志数据 三种方式实现 ODS 层的数据实时接入和实时更新,往上可以通过半小时一次或者更高频率的跑批任务刷新数据到 DWD、DWS、ADS。
4.2 方案二
方案二是用 FlinkSQL 完成 DWD 层数据清洗和表关联,将数据写入 DWD 层,往上逐层进行微批处理。
我们通过 FinkSQL 读取 Kafka 数据后,利用 FlinkSQL 的 ETL 能力,将数据依次加工成 DWD、DWS,然后写入 Doris,在 Doris 中通过报表直接查询 DWS 的数据,完成数据的实时展现。
4.3 方案三
方案三是 Flink 完成 ODS 到 DWD、DWD 到 DWS 的数据加工,并将数据同步写入 Kafka 和 Doris,Doris 只做数据查询,不进行数据加工。
需要通过 FinkSQL 完成数据的全流程加工,直接将 ADS 层的数据写入 Doris,由分析平台直接读取结果展示数据。
4.4 方案四 / 方案五
我们还可以针对路径一和路径二进行优化,将 ODS 或者 DWD 层往上的数据加工替换成视图,然后由数据分析平台直接查询顶层的视图,这样就衍生出了方案四和方案五。方案四和方案五的优点是不需要跑批,可以直接查询最实时的数据,缺点是如果代码过于复杂,会影响前端查询性能。
方案四是将方案一中的数据微批处理改成视图,流批用同一个程序,T+1
数据写入实体表,实时数据写入 ODS 后通过视图获取,对外提供实体表 union all
视图的数据给查询使用。
方案五是将方案二的微批处理改成视图,实时数据写入 DWD,往上利用视图查询当日数据,T+1
数据每日刷新写入实体表。
这五种方案简单实用,虽然无法构建完整的流批一体数仓,但是可以满足大部分实时数仓的需求。之所以提供五个方案,主打一个灵活。
听到这里,可能很多朋友会说,切,你这太简单了吧?这里我会说,简单不好吗?Flink 搞得那么复杂,数据准确性和运维便捷性能超过这五个方案吗?做数仓开发,我从来都崇尚 大道至简,逻辑非常简单都可能会出现 Bug,搞得太过复杂 Bug 不是更多吗?
最后我们再对比一下这五个方案:这五个方案各有优点,也各有缺点,不能简单的说哪个好,哪个不好。各有不同的应用场景:
- 方案一和方案四的应用场景类似,适合没有大表关联的场景或者三个以上的多表关联场景,在查询性能达不到要求的情况下改用方案一微批加工数据。
- 方案二和方案五的应用场景类似,适合两个表(例如头行结构的父子表)关联场景,推荐使用 FinkSQL 双流 Join 完成数据的初步关联,降低查询资源消耗。在后续的查询性能达不到要求情况下采用方案二进行微批加工数据。
- 方案三适合日志数据加工或者对数据准确性要求不高,但是对实时性要求非常高的业务场景。或者每日增量数据特别大,查询太慢、微批处理占用系统资源过多的情况。
以上五个方案都可以实现实时数据和离线数据加工共用一套代码逻辑,降低维度成本,实现了某种程度上的流批一体。
5.不同场景的方案选择
最后,我们再回到前面介绍的八种实时数据的应用场景,根据业务场景的不同,对数据时效性和准确性的要求也不同。
业务场景 | 方案一 | 方案二 | 方案三 | 方案四 | 方案五 |
---|---|---|---|---|---|
监控预警 | ✔️ | ✔️ | |||
实时大屏 | ✔️ | ✔️ | |||
机器人播报 | ✔️ | ✔️ | |||
移动看板 | ✔️ | ✔️ | |||
自助分析 | ✔️ | ✔️ | |||
实时看板 | ✔️ | ✔️ | |||
实时接口 | ✔️ | ✔️ | |||
实时推荐 | ✔️ | ✔️ |
- 监控预警 准确性和时效性要求都很高,但是查询要求不高,所以方案四和方案五均可。
- 实时大屏 的时效性和查询性能要求高,但是准确性可以低一点,因此优选方案三和方案五。
- 机器人播报 则是准确性要求最高,查询性能和时效性要求都不高,因此才有方案一和方案二的跑批模式。
- 移动看板、实时看板 的查询性能要求高,数据时效性也要求很高,准确性可以略低一点,因此推荐方案三和方案五。
- 自助分析 的数据粒度比较细,不需要太过于汇总,查询性能要求高,一般采用方案二和方案五。
- 实时接口 的数据时效性要求高,查询一般是点查,所以一般采用方案四和方案五。
- 实时推荐 的数据时效性要求不高,但是查询性能和数据准确性要求高,一般采用方案一和方案二。