一.OPPO 实时数仓的演进思路

1.1.OPPO 业务与数据规模

大家都知道 OPPO 是做智能手机的,但并不知道 OPPO 与互联网以及大数据有什么关系,下图概要介绍了 OPPO 的业务与数据情况:

OPPO 作为手机厂商,基于 Android 定制了自己的 ColorOS 系统,当前日活跃用户超过 2 亿。围绕 ColorOS,OPPO 构建了很多互联网应用,比如应用商店、浏览器、信息流等。

在运营这些互联网应用的过程中,OPPO 积累了大量的数据,上图右边是整体数据规模的演进:从 2012 年开始每年都是 2~3 倍的增长速度,截至目前总数据量已经超过 100PB,日增数据量超过 200TB。

要支撑这么大的一个数据量,OPPO 研发出一整套的数据系统与服务,并逐渐形成了自己的数据中台体系。

1.2.OPPO 数据中台

今年大家都在谈数据中台,OPPO 是如何理解数据中台的呢?我们把它分成了 4 个层次:

  • 最下层是统一工具体系,涵盖了"接入 - 治理 - 开发 - 消费"全数据链路;
  • 基于工具体系之上构建了数据仓库,划分成"原始层 - 明细层 - 汇总层 - 应用层",这也是经典的数仓架构;
  • 再往上是全域的数据体系,什么是全域呢?就是把公司所有的业务数据都打通,形成统一的数据资产,比如 ID-Mapping、用户标签等;
  • 最终,数据要能被业务用起来,需要场景驱动的数据产品与服务。

以上就是 OPPO 数据中台的整个体系,而数据仓库在其中处于非常基础与核心的位置。

1.3. 构建 OPPO 离线数仓

过往 2、3 年,我们的重点聚焦在离线数仓的构建。上图大致描述了整个构建过程:首先,数据来源基本是手机、日志文件以及 DB 数据库,我们基于 Apache NiFi 打造了高可用、高吞吐的接入系统,将数据统一落入 HDFS,形成原始层;紧接着,基于 Hive 的小时级 ETL 与天级汇总 Hive 任务,分别负责计算生成明细层与汇总层;

最后,应用层是基于 OPPO 内部研发的数据产品,主要是报表分析、用户画像以及接口服务。此外,中间的明细层还支持基于 Presto 的即席查询与自助提数。 伴随着离线数仓的逐步完善,业务对实时数仓的诉求也愈发强烈。

1.5. 离线到实时的平滑迁移

无论是一个平台还是一个系统,都离不开上下两个层次的构成:上层是 API,是面向用户的编程抽象与接口;下层是 Runtime,是面向内核的执行引擎。我们希望从离线到实时的迁移是平滑的,是什么意思呢?从 API 这层来看,数仓的抽象是 Table、编程接口是 SQL+UDF,离线数仓时代用户已经习惯了这样的 API,迁移到实时数仓后最好也能保持一致。而从 Runtime 这层来看,计算引擎从 Hive 演进到了 Flink,存储引擎从 HDFS 演进到了 Kafka。

基于以上的思路,只需要把之前提到的离线数仓 pipeline 改造下,就得到了实时数仓 pipeline。

1.6. 构建 OPPO 实时数仓

从上图可以看到,整个 pipeline 与离线数仓基本相似,只是把 Hive 替换为 Flink,把 HDFS 替换为 Kafka。从总体流程来看,基本模型是不变的,还是由原始层、明细层、汇总层、应用层的级联计算来构成。

因此,这里的核心问题是如何基于 Flink 构建出这个 pipeline,下面就介绍下我们基于 Flink SQL 所做的一些工作。

二. 基于 Flink SQL 的扩展工作

2.1.Why Flink SQL

首先,为什么要用 Flink SQL? 下图展示了 Flink 框架的基本结构,最下面是 Runtime,这个执行引擎我们认为最核心的优势是四个:第一,低延迟,高吞吐;第二,端到端的 Exactly-once;第三,可容错的状态管理;第四,Window & Event time 的支持。基于 Runtime 抽象出 3 个层次的 API,SQL 处于最上层。

Flink SQL API 有哪些优势呢?我们也从四个方面去看:第一,支持 ANSI SQL 的标准;第二,支持丰富的数据类型与内置函数,包括常见的算术运算与统计聚合;第三,可自定义 Source/Sink,基于此可以灵活地扩展上下游;第四,批流统一,同样的 SQL,既可以跑离线也可以跑实时。

那么,基于 Flink SQL API 如何编程呢?下面是一个简单的演示:

首先是定义与注册输入 / 输出表,这里创建了 2 张 Kakfa 的表,指定 kafka 版本是什么、对应哪个 topic;接下来是注册 UDF,篇幅原因这里没有列出 UDF 的定义;最后是才是执行真正的 SQL。可以看到,为了执行 SQL,需要做这么多的编码工作,这并不是我们希望暴露给用户的接口。

2.2. 基于 WEB 的开发 IDE

2.5.Flink SQL 对接外部数据源

搞清楚了 Flink SQL 注册库表的过程,给我们带来这样一个思路:如果外部元数据创建的表也能被转换成 TableFactory 可识别的 map,那么就能被无缝地注册到 TableEnvironment。基于这个思路,我们实现了 Flink SQL 与已有元数据中心的对接,大致过程参见下图:

通过元数据中心创建的表,都会将元数据信息存储到 MySQL,我们用一张表来记录 Table 的基本信息,然后另外三张表分别记录 Connector、Format、Schema 转换成 key-value 后的描述信息。之所以拆开成三张表,是为了能够能独立的更新这三种描述信息。接下来是定制实现的 ExternalCatalog,能够读取 MySQL 这四张表,并转换成 map 结构。

2.6. 实时表 - 维表关联

到目前为止,我们的平台已经具备了元数据管理与 SQL 作业管理的能力,但是要真正开放给用户使用,还有一点基本特性存在缺失。通过我们去构建数仓,星型模型是无法避免的。这里有一个比较简单的案例:中间的事实表记录了广告点击流,周边是关于用户、广告、产品、渠道的维度表。

假定我们有一个 SQL 分析,需要将点击流表与用户维表进行关联,这个目前在 Flink SQL 中应该怎么来实现?我们有两种实现方式,一个基于 UDF,一个基于 SQL 转换。

三.构建实时数仓的应用案例

下面分享几个典型的应用案例,都是在我们的平台上用 Flink SQL 来实现的。

3.1. 实时 ETL 拆分

这里是一个典型的实时 ETL 链路,从大表中拆分出各业务对应的小表:

OPPO 的最大数据来源是手机端埋点,从手机 APP 过来的数据有一个特点,所有的数据是通过统一的几个通道上报过来。因为不可能每一次业务有新的埋点,都要去升级客户端,去增加新的通道。比如我们有个 sdk_log 通道,所有 APP 应用的埋点都往这个通道上报数据,导致这个通道对应的原始层表巨大,一天几十个 TB。但实际上,每个业务只关心它自身的那部分数据,这就要求我们在原始层进行 ETL 拆分。

这个 SQL 逻辑比较简单,无非是根据某些业务字段做筛选,插入到不同的业务表中去。它的特点是,多行 SQL 最终合并成一个 SQL 提交给 Flink 执行。大家担心的是,包含了 4 个 SQL,会不会对同一份数据重复读取 4 次?其实,在 Flink 编译 SQL 的阶段是会做一些优化的,因为最终指向的是同一个 kafka topic,所以只会读取 1 次数据。

另外,同样的 Flink SQL,我们同时用于离线与实时数仓的 ETL 拆分,分别落入 HDFS 与 Kafka。Flink 中本身支持写入 HDFS 的 Sink,比如 RollingFileSink。

3.2. 实时指标统计

这里是一个典型的计算信息流 CTR 的这个案例,分别计算一定时间段内的曝光与点击次数,相除得到点击率导入 Mysql,然后通过我们内部的报表系统来可视化。这个 SQL 的特点是它用到了窗口 (Tumbling Window) 以及子查询。

3.3. 实时标签导入

这里是一个实时标签导入的案例,手机端实时感知到当前用户的经纬度,转换成具体 POI 后导入 ES,最终在标签系统上做用户定向。

这个 SQL 的特点是用了 AggregateFunction,在 5 分钟的窗口内,我们只关心用户最新一次上报的经纬度。AggregateFunction 是一种 UDF 类型,通常是用于聚合指标的统计,比如计算 sum 或者 average。在这个示例中,由于我们只关心最新的经纬度,所以每次都替换老的数据即可。

四. 未来工作的思考和展望

最后,给大家分享一下关于未来工作,我们的一些思考与规划,还不是太成熟,抛出来和大家探讨一下。

4.1. 端到端的实时流处理

什么是端到端?一端是采集到的原始数据,另一端是报表 / 标签 / 接口这些对数据的呈现与应用,连接两端的是中间实时流。当前我们基于 SQL 的实时流处理,源表是 Kafka,目标表也是 Kafka,统一经过 Kafka 后再导入到 Druid/ES/HBase。

这样设计的目的是提高整体流程的稳定性与可用性:首先,kafka 作为下游系统的缓冲,可以避免下游系统的异常影响实时流的计算(一个系统保持稳定,比起多个系统同时稳定,概率上更高点);其次,kafka 到 kafka 的实时流,exactly-once 语义是比较成熟的,一致性上有保证。

然后,上述的端到端其实是由割裂的三个步骤来完成的,每一步可能需要由不同角色人去负责处理:数据处理需要数据开发人员,数据导入需要引擎开发人员,数据资产化需要产品开发人员。

我们的平台能否把端到端给自动化起来,只需要一次 SQL 提交就能打通处理、导入、资产化这三步?在这个思路下,数据开发中看到的不再是 Kafka Table,而应该是面向场景的展示表 / 标签表 / 接口表。比如对于展示表,创建表的时候只要指定维度、指标等字段,平台会将实时流结果数据从 Kafka 自动导入 Druid,再在报表系统自动导入 Druid 数据源,甚至自动生成报表模板。

4.2. 实时流的血缘分析

关于血缘分析,做过离线数仓的朋友都很清楚它的重要性,它在数据治理中都起着不可或缺的关键作用。对于实时数仓来说也莫不如此。我们希望构建端到端的血缘关系,从采集系统的接入通道开始,到中间流经的实时表与实时作业,再到消费数据的产品,都能很清晰地展现出来。基于血缘关系的分析,我们才能评估数据的应用价值,核算数据的计算成本。

4.3. 离线 - 实时数仓一体化

最后提一个方向是离线实时数仓的一体化。我们认为短期内,实时数仓无法替代离线数仓,两者并存是新常态。在离线数仓时代,我们积累的工具体系,如何去适配实时数仓,如何实现离线与实时数仓的一体化管理?理论上来讲,它们的数据来源是一致的,上层抽象也都是 Table 与 SQL,但本质上也有不同的点,比如时间粒度以及计算模式。对于数据工具与产品来说,需要做哪些改造来实现完全的一体化,这也是我们在探索和思考的。

基于Flink构建的实时数据仓库,这才是OPPO数据中台的基础相关推荐

  1. 基于 Flink 构建大规模实时风控系统在阿里巴巴的落地

    目前 Flink 基本服务于集团的所有 BU ,在双十一峰值的计算能力达到 40 亿条每秒,计算任务达到了 3 万多个,总共使用 100 万+ Core :几乎涵盖了集团内的所有具体业务,比如:数据中 ...

  2. 网络安全公司奇安信集团是如何基于 Flink 构建 CEP 引擎实时检测网络攻击【未来不可忽视的网络安全】

    摘要: 奇安信集团作为一家网络安全公司是如何基于 Flink 构建 CEP 引擎实时检测网络攻击?其中面临的挑战以及宝贵的实践经验有哪些?本文主要内容分为以下四个方面: 背景及现状 技术架构 产品及运 ...

  3. 如何基于Flink+TensorFlow打造实时智能异常检测平台?只看这一篇就够了

    作者 | 潘国庆编辑 | Natalie AI 前线导读:Flink 已经渐渐成为实时计算引擎的首选之一,从简单的实时 ETL 到复杂的 CEP 场景,Flink 都能够很好地驾驭.本文整理自携程实时 ...

  4. 阿里云实时计算产品经理李佳林:基于 Flink 构建大规模风控系统的技术实战

    本⽂由 Flink 社区志愿者邹志业整理,内容来源⾃阿里云实时计算产品经理李佳林在 7 月 5 日 Flink 峰会(CSDN 云原生系列)的演讲.主要内容包括:基于 Flink 构建风控系统.阿里风 ...

  5. 基于 Flink 构建关联分析引擎的挑战和实践

    点击上方"zhisheng",选择"设为星标" 公众号(zhisheng)内回复:ffa 可以获取到所有 PPT 和视频 随着云计算.大数据等新一代IT技术在各 ...

  6. 快手基于 Flink 构建实时数仓场景化实践

    摘要:本文整理自快手数据技术专家李天朔在 5 月 22 日北京站 Flink Meetup 分享的议题<快手基于 Flink 构建实时数仓场景化实践>,内容包括: 快手实时计算场景 快手实 ...

  7. clickhouse 航空数据_趣头条基于Flink+ClickHouse的实时数据分析平台

    原标题:趣头条基于Flink+ClickHouse的实时数据分析平台 分享嘉宾:王金海 趣头条 编辑整理:王彦 内容来源:Flink Forward Asia 出品平台:DataFunTalk 导读: ...

  8. 基于Flink的个人装扮商城群体用户画像与数据实时统计系统(六)-需求集C实现

    文章目录 一.需求集C有什么? 二.模拟生成用户购买商品的信息 三.需求集C实现 一.需求集C有什么? 所有需求link:基于Flink的个人装扮商城群体用户画像与数据实时统计系统(二)-项目介绍与需 ...

  9. 基于Sphinx构建准实时更新的分布式通用搜索引擎平台

     亿级数据的高并发通用搜索引擎架构设计[原创]   大 |  中 |  小  [  2008-12-9 08:47 | by  张宴 ] [文章作者:张宴 本文版本:v1.0 最后修改:2008.12 ...

最新文章

  1. Android爬坑之旅:软键盘挡住输入框问题的终极解决方案
  2. 计算机硬盘冒烟了,电脑硬盘冒烟损坏了怎么办?
  3. PyTorch | 通过torch.eye创建单位对角矩阵 | torch.eye()如何使用?torch.eye()例子 | torch.eye()使用方法
  4. Linux 下DNS服务配置
  5. python编写个人信息_Python爬取个人微信朋友信息操作示例
  6. Windows7开机加速全攻略
  7. 探索另类圆环图的做法
  8. 伺服舵机匀加速和匀减速运动Demo
  9. 趋势杀毒软件卸载方法(卸载密码破解)
  10. 评分卡分箱原则及单调性
  11. openwrt-17.01.6 LEDE下载
  12. 世界著名的数学猜想,你知道几个?
  13. 银河麒麟识别不了U盘
  14. 『现学现忘』Docker相关概念 — 1、云计算概念
  15. CSS 按钮悬停效果
  16. linux开机卡在usb,UUI v1.9.7.3 轻松制作 Linux 版 USB 开机随身碟、记忆卡(Universal USB Installer)...
  17. java不会英语可以学习吗,详细说明
  18. Vue列表渲染v-for ... of ... 与 v-for ... in ...区别
  19. astype函数的使用
  20. 传统防火墙与Web应用程序防火墙(WAF)的区别

热门文章

  1. 使用 xxd 修改二进制文件
  2. 国内学历证书的类别有哪些?
  3. Part I 空气曲棍球 Chapter8(8.3 Adding an Object Builder)
  4. MySQL结构化查询语言
  5. 艾美捷支原体检测试剂盒基本参数和样本数据分析
  6. 基于word2vec的中文词向量训练
  7. 什么是SSH与SSH客户端
  8. h5精准定位_手机端H5地理定位结合腾讯地图API实现精准定位!
  9. 织梦二开问答模块插件-支持伪静态利于收录及排名
  10. 逻辑回归模型小结--基于评分模型