本文来自 OPPO 大数据平台研发负责人张俊在 Flink Forward Asia上的分享。OPPO 基于 Apache Flink 构建实时数仓,在数据规模上单日总数据处理量超 10 万亿,峰值大概超过每秒 3 亿。本文内容分为如下四个方面:数据库
关于做者:张俊,OPPO 大数据平台研发负责人,主导了 OPPO 涵盖“数据接入-数据治理-数据开发-数据应用”全链路的数据中台建设。2011年硕士毕业于上海交通大学,曾前后工做于摩根士丹利、腾讯,具备丰富的数据系统研发经验,目前重点关注数仓建设、实时计算、OLAP 引擎方向,同时也是Flink开源社区贡献者。后端
你们都认为 OPPO 是一家手机公司,但你们可能并不清楚,其实 OPPO 也会作与移动互联网相关的业务。在 2019 年 12 月,OPPO 发布了本身定制的手机操做系统 ColorOS 7.0 版本。目前包括海外市场在内,ColorOS 的日活已经超过了 3 亿。ColorOS 内置了不少移动互联网服务,包括应用商店、云服务、游戏中心等,而这些服务的日活也达到了几千万级别。架构
为了支撑这些移动互联网服务,OPPO 创建了以下图以数仓为核心的数据架构。图中蓝色的部分,相信你们应该都很熟悉,这部分基本上都是一些开源的组件,从数据接入,到基于数仓实现交互式查询、数据处理,再到数据应用。其中的应用主要分为三个方面:并发
在过去几年的时间里面,OPPO 内部的这套以数仓为核心的数据架构已经逐渐开始成熟了。框架
可是随着业务的发展以及数据规模的不断膨胀,OPPO 对于数仓实时化的诉求愈来愈强烈。OPPO 对于数仓实时化的诉求能够分为两个维度,即业务维度和平台维度。性能
目前 OPPO 实时数仓的规模是 Flink 已经达到了 500 多个节点,Kafka 大概达到了 200 多个节点。在元数据维度,实时数据库表达到了 500 多张,实时做业大概有 300 多个。在数据规模维度,天天总数据处理量超过了 10 万亿,峰值大概超过每秒 3 亿。大数据
谈到实时数仓的顶层设计,也不得不谈到实时数仓的底层逻辑,由于底层逻辑决定顶层设计,而底层逻辑则来自于实时的观察。优化
下图中将实时数仓和离线数仓放在一块儿进行了对比,发现二者的类似性不少,不管是数据来源、数据使用者、数据开发人员以及数据应用都很是类似,二者最大的差别点在于时效性,由于实时数仓中数据的时效性须要达到分钟级或者秒级。ui
当有了对于底层逻辑的观察以后,就可以推导出顶层设计状况。OPPO 但愿所设计出来的实时数仓可以实现从离线到实时的平滑迁移,以前你们如何使用和开发离线数仓,现在到了实时数仓也但愿你们如何开发和使用。一般而言,当设计一款产品或者平台的时候,能够划分为两层,即底层实现和上层抽象。对于底层实现而言,可能会有不一样的技术,从 Hive 到 Flink,从 HDFS 到 Kafka。而在上层抽象而言,则但愿对于用户而言是透明的。spa
不管是离线仍是实时,最终都但愿数仓的核心抽象就是一个 Table,围绕着这个核心的抽象,上面还有三个维度的抽象。
从以上三个抽象维度来看,咱们但愿从离线到实时可以将抽象保持一致的,这样对于用户而言成本是最低的。接下来则会为你们介绍如何将迁移的成本保持最低。
首先为你们介绍离线实时一体化接入链路,OPPO 的数据从手机端到 OBus 内部数据收集服务,收集以后会统一落入到Kafka中去,再经过 Flink SQL 的任务能够同时落入 HDFS 和 Kafka 中去。Flink 能够实现数据通道的拆分,对于 OPPO 这样一个手机公司而言,不少 APP 上报都是经过同一条通道,所以在将数据落入到数仓以前须要对于数据通道进行拆分,根据不一样的业务和属性作一些拆分,除此以外还会作一些格式的转换。另一部分功能就是实现数据的监控,由于将数据落入到 HDFS 时须要有一个很重要的问题就是分区感知问题,好比离线 ETL 任务如何知道分区已经结束了。
OPPO 的作法是根据端到端不一样数据的对帐实现的,所以须要在 Flink SQL 这一层完整地记录收到多少条数据,写入了多少条数据,而后和前面的 OBus 作一个数据对帐的对比,若是对比结果在必定范围以内,就能够写一个成功文件,这样就可让后端的 ETL 任务开始运行。
使用 Flink SQL 所 带来的好处在于
对于数仓的管理流程而言,无非就是元数据是如何管理的,表的字段是如何定义的,表的血缘如何追踪以及表的权限如何管理,以及表的监控如何实现。现在在 OPPO 内部,离线和实时数仓的这些管理流程可以作到一致,首先二者使用的流程是一致的,其次表的 Schema 的定义以及表的血缘可以保证一致,而不须要用户从新申请和定义。
对于数仓的开发而言,抽象下来能够分为三个层面,即离线批处理的开发、流式开发以及交互式查询。而对于用户而言,但愿可以保证用户体验的一致,而且但愿实现开发流程的统一。
以下图所示的是 OPPO 实时数仓的分层结构,从接入层过来以后,全部的数据都是会用 Kafka 来支撑的,数据接入进来放到 Kafka 里面实现 ODS 层,而后使用 Flink SQL 实现数据的清洗,而后就变到了 DWD 层,中间使用 Flink SQL 实现一些聚合操做,就到了 ADS 层,最后根据不一样的业务使用场景再导入到ES等系统中去。固然,其中的一些维度层位于 MySQL 或者 Hive 中。
对于数仓领域的近期发展而言,其中颇有意思的一点是:不管是离线仍是实时的数据架构,都慢慢演进成了 SQL 一统天下的架构。不管是离线仍是实时是数据仓库,不管是接入,查询、开发仍是业务系统都是在上面写 SQL 的方式。
前面为你们分享了 OPPO 实时数仓实践的顶层设计,固然这部分并无所有实现,接下来为你们分享 OPPO 已经有的落地实践,
想要作实时数仓所须要的第一步就是支持 SQL 的开发与元数据管理的实现。OPPO 在这部分的设计大体以下图所示。
这里须要元数据系统和开发系统,须要可以在元数据系统中建立实时表并在开发系统里面建立实时做业并写 SQL,而不管是建立 Table 仍是 Job,都须要可以持久化到 MySQL 里面去。
而后再去扩展 Flink 里面的组件,并将其从 MySQL 里面加载出来。
在 OPPO 的场景下,咱们发现了本身所存在的一个很棘手的问题,那就是不少用户在写 SQL 的时候会出现同一个做业须要写多个 SQL,好比刚才提到的接入场景,若是想要作通道的拆分,一般而言须要来自同一个表格,通过不一样的过滤,而后导入到不一样的数据表里面去,而 OPPO 但愿在单个做业中就可以实现这样的表达。
可是这样作所带来的问题就是将多个 SQL 放在一个做业里面执行就会生成多个 Data Source,多个 Data Source 就会重复地消费 Kafka,这就使得 Kafka 集群的压力很是大,缘由是不少 Kafka 机器的写入和读取的操做比例差距很是大,一个 SQL 的做业可能会读取不少次 Kafka 的 Topic。而这是没有必要的,由于对于同一次做业而言,只须要消费一次 Kafka 便可,接下来数据能够在 Flink 内部进行消化和传播。
OPPO 针对于上述问题实现了一个很是巧妙的优化,由于 Flink 的 SQL 会生成一个 Job Graph,在这以前会生成一个 Stream Graph。而 OPPO 经过改写 Stream Graph,使得不管用户提交多少个 SQL,对应只有一个 Data Source,这样就下降了对于 Kafka 的消费量,并且带为用户来了很大的收益。
线上 BI 的实时报表是很是通用的场景,对于实时报表而言,每每须要三个环节的配合:
上述链路中的数据处理、数据导入和数据展示三个环节是比较割裂的,所以须要三种不一样角色的人员来介入作这件事情,所以 OPPO 但愿可以打通实时数据链路。OPPO 作了以下图所示的实时数据链路的自动化,对于 Kafka 的表作了抽象,而对于用户而言,其就是用于作 BI 展现的表,Kafka 的表须要定义哪些是维度、哪些是指标,这是作报表展现最基本的字段定义。
当完成了上述任务以后,就能够将整个实时数据链路以自动化的方式串起来。当用户将 SQL 写完以后,能够自动化地探测 Report Table 须要导入到 Druid 里面去,以及哪些是指标,哪些是维度,而且能够将数据从 Druid 自动地导入到 BI 系统。这样一来,对于用户而言只须要写一个 SQL,以后就能够在 BI 系统之上看到报表了。
以前,OPPO 作数据链路的延迟监控时也属于单个点进行监控的,能够从下图中看出至少有三级的 Kafka 的 Topic,对于每一个 Topic 都存在延迟的监控。而对于用户而言,关注的并非点,而是面,也就是最终展示的数据报表中延迟状况如何。
所以, OPPO 也实现了全链路的延迟监控,从接入的通道开始到每一层的 Kafka 消费,都将其 lag 状况汇总起来,探索到每一级的 Flink SQL 表的血缘关系。有了这样的血缘关系以后就能够从 Druid 表推导到前面所接入的链路是哪个,而后将整体延迟加起来,这样就能够反映出总体链路的延迟状况。
对于实时数据链路而言,多租户管理一样很是重要。OPPO 在这部分的实践的核心是两点:
由于 OPPO 如今的实时数仓是基于 SQL 作的,因此在将来但愿可以具备更好的、更便捷的 SQL 开发能力,总结来下就是如下四点:
目前,OPPO 是基于 YARN 作 Flink 的集群调度,而 YARN 的调度是基于 VCore 以及内存维度实现的。在线上运行时就发现一些机器的 CPU 利用率很高,另一些却很低,这是由于不一样的 SQL 处理的复杂度以及计算密集度是不一样的,若是仍是和之前同样分配 VCore,那么极可能致使对于资源的利用率不一样,所以将来须要考虑将 SQL 对于资源的调度加入到考虑范围内,尽可能避免资源的倾斜。
对于数据分析师而言,你们都知道Flink里面存在一些高级配置。除了写 SQL 以外,还有不少其余的知识,好比操做的并发度、状态后台以及水位间隔等,可是用户每每会很难掌握如何配置这些复杂参数,所以 OPPO 但愿将来可以将这些复杂的参数配置实现自动化。经过理解数据的分布状况和 SQL 的复杂状况,自动地配置这些参数。
更进一步,能够从自动化实现自适应,变成智能化,也就是自动化的伸缩调优。之因此要作自动化的伸缩,主要是由于两点,第一,数据分布自己就是存在波动性的;第二,机器在不一样的时间段也存在不一样的状态,所以须要及时探测和修复。所以,自动化的伸缩调优对于大规模集群的成本节省是相当重要的。