数据仓库概念的提出都要追溯到上世纪了,我们认为在大数据元年之前的数仓可以称为传统数仓,而后随着海量数据不断增长,以及Hadoop生态不断发展,主要基于Hive/HDFS的离线数仓架构可以兴起并延续至今,近几年随着Storm/Spark(Streaming)/Flink等实时处理框架的更新迭代乃至相互取代,各厂都在着力构建自己的实时数仓,特别是近两年,随着Flink声名鹊起,实时数仓更是名声在外并且还在不断快速发展。
目前大多企业的数据体系都是围绕数仓的数据平台架构,特别是在着力建设实时数仓,或者在建设离线数仓与实时数仓相统一的数仓体系。本文我们精选了实时数仓建设的典型代表,包括美团点评、网易、知乎、OPPO等几家的实时数仓架构,他们的数仓实践肯定对我们有所借鉴或启迪。笔者这里特别推荐参考他们的分层设计,存储与计算引擎的选型。
本文举的四个代表案例:
- 美团点评基于 Flink 的实时数仓平台实践
- 网易基于Flink的严选实时数仓实践
- 知乎实时数仓实践及架构演进
- OPPO 实时数仓揭秘及离线到实时的平滑迁移
从中提炼出最精彩的内容。感谢以上文章作者的技术分享,所有内容版权归其个人及相关社区所有,文末给出了原文链接。
美团点评基于Flink的实时数仓平台实践
实时计算平台架构
下图所示的是美团点评实时计算平台的架构。
- 最底层是收集层,这一层负责收集用户的实时数据,包括 Binlog、后端服务日志以及 IoT 数据,经过日志收集团队和 DB 收集团队的处理,数据将会被收集到 Kafka 中。这些数据不只是参与实时计算,也会参与离线计算。
- 收集层之上是存储层,这一层除了使用 Kafka 做消息通道之外,还会基于 HDFS 做状态数据存储以及基于 HBase 做维度数据的存储。
- 存储层之上是引擎层,包括 Storm 和 Flink。实时计算平台会在引擎层为用户提供一些框架的封装以及公共包和组件的支持。
- 在引擎层之上就是平台层了,平台层从数据、任务和资源三个视角去管理。
- 架构的最上层是应用层,包括了实时数仓、机器学习、数据同步以及事件驱动应用等。
从功能角度来看,美团点评的实时计算平台主要包括作业和资源管理两个方面的功能。其中,作业部分包括作业配置、作业发布以及作业状态三个方面的功能。
- 在作业配置方面,则包括作业设置、运行时设置以及拓扑结构设置;
- 在作业发布方面,则包括版本管理、编译/发布/回滚等;
- 作业状态则包括运行时状态、自定义指标和报警以及命令/运行时日志等。
在资源管理方面,则为用户提供了多租户资源隔离以及资源交付和部署的能力。
传统数仓模型
为了更有效地组织和管理数据,数仓建设往往会进行数据分层,一般自下而上分为四层:ODS(操作数据层)、DWD(数据明细层)、DWS(汇总层)和应用层。即时查询主要通过 Presto、Hive 和 Spark 实现。
实时数仓模型
实时数仓的分层方式一般也遵守传统数据仓库模型,也分为了 ODS 操作数据集、DWD 明细层和 DWS 汇总层以及应用层。但实时数仓模型的处理的方式却和传统数仓有所差别,如明细层和汇总层的数据一般会放在 Kafka 上,维度数据一般考虑到性能问题则会放在 HBase 或者 Tair 等 KV 存储上,即席查询则可以使用 Flink 完成。
准实时数仓模型
在以上两种数仓模型之外,我们发现业务方在实践过程中还有一种准实时数仓模型,其特点是不完全基于流去做,而是将明细层数据导入到 OLAP 存储中,基于 OLAP 的计算能力去做汇总并进行进一步的加工。
实时数仓和传统数仓的对比主要可以从四个方面考虑:
- 第一个是分层方式,离线数仓为了考虑到效率问题,一般会采取空间换时间的方式,层级划分会比较多;则实时数仓考虑到实时性问题,一般分层会比较少,另外也减少了中间流程出错的可能性。
- 第二个是事实数据存储方面,离线数仓会基于 HDFS,实时数仓则会基于消息队列(如 Kafka)。
- 第三个是维度数据存储,实时数仓会将数据放在 KV 存储上面。
- 第四个是数据加工过程,离线数仓一般以 Hive、Spark 等批处理为主,而实时数仓则是基于实时计算引擎如 Storm、Flink 等,以流处理为主。
网易基于Flink的严选实时数仓实践
整体架构
实时数仓整体框架依据数据的流向分为不同的层次,接入层会依据各种数据接入工具收集各个业务系统的数据,如买点的业务数据或者业务后台的并购放到消息队列里面。消息队列的数据既是离线数仓的原始数据,也是实时计算的原始数据,这样可以保证实时和离线的原始数据是统一的。有了源数据,在计算层经过FLink 实时计算引擎做一些加工处理,然后落地到存储层中不同存储介质当中。不同的存储介质是依据不同的应用场景来选择。框架中还有FLink和Kafka的交互,在数据上进行一个分层设计,计算引擎从Kafka中捞取数据做一些加工然后放回Kafka。在存储层加工好的数据会通过服务层的两个服务:统一查询、指标管理,统一查询是通过业务方调取数据接口的一个服务,指标管理是对数据指标的定义和管理工作。通过服务层应用到不同的数据应用,数据应用可能是我们的正式产品或者直接的业务系统。后面会从数据的分层设计和具体的实现两个方面介绍。
整体设计
上面是对数据的整体设计,主要参考了离线数仓的设计方案,也参考了业界同行的一些做法。将数据分为四个层次:
首先是ODS层,即操作数据层,通过数据采集工具收集各个业务源数据;DWD层,明细数据层是按主题域来划分,通过维度建模方式来组织各个业务过程的明细数据。中间会有一个DIM层,维度数据层主要做一些查询和关联的操作。最上层是DM层,通过DWD层数据做一些指标加工,主要面向一些分析和应用汇总的指标或者是做多维分析的明细数据。
技术实现
然后介绍下技术实现方面的考量,主要分为计算和存储。对于计算方面,有很多实时计算引擎,有Flink、Storm、Spark Streaming,Flink相对于Storm的优势就是支持SQL,相对于Spark Streaming又有一个相对好的性能表现。同时Flink在支持好的应用和性能方面还有比较好的语义支持和比较好的容错机制,因此构建实时数仓Flink是一个比较好的实时计算引擎选择。
技术实现中Flink的具体作用:
Flink作为实时的计算引擎,不同的数据层(ods->dwd->dm)之间,不同的存储引擎(kafka->db)都是通过Flink job串联的,相关的etl和关联、聚合等操作也是在Flink中完成。
对于存储层会依据不同的数据层的特点选择不同的存储介质,ODS层和DWD层都是存储的一些实时数据,选择的是Kafka进行存储,在DWD层会关联一些历史明细数据,会将其放到Redis里面。在DIM层主要做一些高并发维度的查询关联,一般将其存放在HBase里面,对于DIM层比价复杂,需要综合考虑对于数据落地的要求以及具体的查询引擎来选择不同的存储方式。对于常见的指标汇总模型直接放在MySQL里面,维度比较多的、写入更新比较大的模型会放在HBase里面,还有明细数据需要做一些多维分析或者关联会将其存储在Greenplum里面,还有一种是维度比较多、需要做排序、查询要求比较高的,如活动期间用户的销售列表等大列表直接存储在Redis里面。
知乎实时数仓架构实践与演进
本文主要讲述知乎的实时数仓实践以及架构的演进,这包括以下几个方面:
- 实时数仓 1.0 版本,主题:ETL 逻辑实时化,技术方案:Spark Streaming。
- 实时数仓 2.0 版本,主题:数据分层,指标计算实时化,技术方案:Flink Streaming。
- 实时数仓未来展望:Streaming SQL 平台化,元信息管理系统化,结果验收自动化。
实时数仓 1.0
第一部分是数据采集,由三端 SDK 采集数据并通过 Log Collector Server 发送到 Kafka。第二部分是数据 ETL,选择了 Spark Streaming 作为实时数据的处理框架,主要完成对原始数据的清洗和加工并分实时和离线导入 Druid。第三部分是数据可视化,由 Druid 负责计算指标并通过 Web Server 配合前端完成数据可视化。
1.0 版本的实时数仓有以下几个不足:
- 所有的流量数据存放在同一个 Kafka Topic 中,如果下游每个业务线都要消费,这会导致全量数据被消费多次,Kafka 出流量太高无法满足该需求。
- 所有的指标计算全部由 Druid 承担,Druid 同时兼顾实时数据源和离线数据源的查询,随着数据量的暴涨 Druid 稳定性急剧下降,这导致各个业务的核心报表不能稳定产出。
- 由于每个业务使用同一个流量数据源配置报表,导致查询效率低下,同时无法对业务做数据隔离和成本计算。
随着数据量的暴涨,Druid 中的流量数据源经常查询超时同时各业务消费实时数据的需求也开始增多,如果继续沿用实时数仓 1.0 架构,需要付出大量的额外成本。于是,在实时数仓 1.0 的基础上,我们建立起了实时数仓 2.0,梳理出了新的架构设计并开始着手建立实时数仓体系,新的架构如下图所示。
实时数仓 2.0
相比实时数仓 1.0 以 Spark Streaming 作为主要实现技术,在实时数仓 2.0 中,我们将 Flink 作为指标汇总层的主要计算框架。Flink 相比 Spark Streaming 有更明显的优势,主要体现在:低延迟、Exactly-once 语义支持、Streaming SQL 支持、状态管理、丰富的时间类型和窗口计算、CEP 支持等。
从实时数仓 1.0 到 2.0,不管是数据架构还是技术方案,我们在深度和广度上都有了更多的积累。随着公司业务的快速发展以及新技术的诞生,实时数仓也会不断的迭代优化。短期可预见的我们会从以下方面进一步提升实时数仓的服务能力:
- Streaming SQL 平台化。目前 Streaming SQL 任务是以代码开发 maven 打包的方式提交任务,开发成本高,后期随着 Streaming SQL 平台的上线,实时数仓的开发方式也会由 Jar 包转变为 SQL 文件。
- 实时数据元信息管理系统化。对数仓元信息的管理可以大幅度降低使用数据的成本,离线数仓的元信息管理已经基本完善,实时数仓的元信息管理才刚刚开始。
- 实时数仓结果验收自动化。对实时结果的验收只能借助与离线数据指标对比的方式,以 Hive 和 Kafka 数据源为例,分别执行 Hive SQL 和 Flink SQL,统计结果并对比是否一致实现实时结果验收的自动化。
OPPO 实时数仓揭秘:从顶层设计实现离线与实时的平滑迁移
以数仓为中心的数据架构
在过去几年的时间里面,OPPO 内部的这套以数仓为核心的数据架构已经逐渐开始成熟了。
离线到实时数仓的平滑迁移
OPPO 希望所设计出来的实时数仓能够实现从离线到实时的平滑迁移,之前大家如何使用和开发离线数仓,如今到了实时数仓也希望大家如何开发和使用。通常而言,当设计一款产品或者平台的时候,可以划分为两层,即底层实现和上层抽象。对于底层实现而言,可能会有不同的技术,从 Hive 到 Flink,从 HDFS 到 Kafka。而在上层抽象而言,则希望对于用户而言是透明的。
实时数仓的层级划分
如下图所示的是 OPPO 实时数仓的分层结构,从接入层过来之后,所有的数据都是会用 Kafka 来支撑的,数据接入进来放到 Kafka 里面实现 ODS 层,然后使用 Flink SQL 实现数据的清洗,然后就变到了 DWD 层,中间使用 Flink SQL 实现一些聚合操作,就到了 ADS 层,最后根据不同的业务使用场景再导入到ES等系统中去。当然,其中的一些维度层位于 MySQL 或者 Hive 中。
SQL一统天下的数据架构
对于数仓领域的近期发展而言,其中很有意思的一点是:无论是离线还是实时的数据架构,都慢慢演进成了 SQL 一统天下的架构。无论是离线还是实时是数据仓库,无论是接入,查询、开发还是业务系统都是在上面写 SQL 的方式。
写在最后的话
总结下,实时数仓主要有两个要点。首先是分层设计上,一般也是参考离线数仓的设计,通常会分为ODS操作数据层、DWD明细层、DWS汇总层以及ADS应用层,可能还会分出一层DIM维度数据层。另外分层设计上也有不同的思路,比如可以将DWS和ADS归为DM数据集市层,网易严选就是这样设计的。
技术选型上,离线数仓一般依托HDFS或Hive构建,选择MR或Spark计算引擎;实时数仓存储层更多是选择Kafka等消息引擎,通常明细层和汇总层都放在Kafka,计算层则多是选择Flink/Spark Streaming/Storm,这方面Flink更有优势,社区也更倾向于选择Flink。大概总结这么多,笔者才疏学浅,有不同看法的同学欢迎留言讨论。
参考:
[1] 美团点评基于 Flink 的实时数仓平台实践
[2]「回顾」基于Flink的严选实时数仓实践
[3] 知乎实时数仓实践及架构演进:https://zhuanlan.zhihu.com/p/56807637
[4] OPPO 实时数仓揭秘:从顶层设计实现离线与实时的平滑迁移