分享嘉宾:五羖 阿里文娱 技术专家
编辑整理:汤志敏
出品平台:DataFunTalk、AI 启蒙者
导读: 数据驱动的方法论已深入人心,无论是开发、产品还是运营,根据数据进行决策是必备环节。你是否好奇过,在优酷这样海量数据的场景下,是什么样的引擎在支撑着业务上林林总总的分析需求?大数据领域中,Kylin、Druid、ES、ADB、GreenPlum、ODPS 这些眼花缭乱的名字,它们之间又要什么区别和联系、企业如何进行选型?本文将为揭晓答案。
目前优酷的工作类型广泛,既有会员营销这种比较复杂的分析,又有优酷播放器性能优化这种对实时性要求比较强的业务需求,在不同的业务场景里面需要使用不同 OLAP 引擎来达到不同的效果。本文的主要内容包括:
- 大数据给传统数据技术带来的挑战
- 市面上各类大数据 OLAP 技术方案一览
- 优酷不同业务场景的 OLAP 选型
01 大数据给传统数据技术带来的挑战
我们知道,大数据在市场分析、性能诊断、客户关系、数据运营、广告投放等都占据着重要的地位。同时,在利用大数据的过程中,也给我们带来了诸多挑战:
1. 大数据带来的挑战
在实际应用中的数据处理速度,假定是亿级数据量,如果使用传统的 MySQL 进行分析需要耗时 19 分钟。
2. 应对挑战
那遇到这样的问题有什么样的解决方案呢,通过对各 OLAP 引擎的观察,我分成了两大类:
- 加并发:一个 MySQL 处理需要 19 分钟,那么添加多个数据实例并行计算,来减少时间。但实现是存在一定困难的。
- 预计算:虽然说 19 分钟速度是挺慢的,但是可以在预定的时间来跑数据,将数据存在性能较好的数据库里,要求是不存在原始的零星数据。预计算以后再去查询,速度会有很大改善。
这是我总结的两个在大数据下处理速度很慢问题的解决方案。下面我们来看看市面上具体的解决方案有哪些。
02 市面上各类大数据 OLAP 技术方案一览
1. 加并发:MPP 架构
第一类的加并发方案,类似之前所说的添加多个 MySQL,GREENPLUM 引擎也是基于一个传统的关系型数据库 PostgreSQL,在 GREENPLUM 里面有多个 PostgreSQL 实例,每个实例都有 Master 节点去管理,再将接收到的请求拆分后分发到各实例,再将实例集中在一起返回,这就是一个 MPP 架构的基本原理。
MPP 架构的缺陷
左边图是一个 GREENPLUM 的大致计算流程。不同的 MPP 架构会有所区别,但是大致原理都是差不多的,每次计算是所有节点都参与计算。
举个例子:使用 group by 将每个节点上 a 和 b 的数量计算出来,每个节点都做这样的运算,计算完之后会有一个 Redistribute 的过程,将所有 key 到一个节点上再去合并,最后 master 将数据收集起来完成计算。
存在的问题是所有的节点都参与计算,不存在特别强的水平拓展性,如果有千万级的节点必然会发生硬件故障,导致容量存在明显的天花板。
2. 加并发:批处理架构
应对这样的问题的解决方案是使用批处理的架构来解决。我们平常使用的批处理架构,MR 和 Spark,并不需要所有的节点都参与运算,它在一个任务事件下发以后,控制节点会分配给一些集群中的节点,而这些节点各自完成自己的计算,然后把计算结果写到磁盘里,再交给下一个计算的节点去写入,每次不需要所有的节点去参与运算。因为节点和它的任务是解耦的,控制节点可以调节分配任务,来减少短板,大规模的水平扩容不会有太大的问题,但却需要一定的代价。
为什么 MPP 需要所有的节点去参与运算?因为运算的结果还要通过通信的方式给其他节点来进行下一步的计算,包括资源存储中各个节点是不共享的,所以需要所有的节点参与运算。
批处理架构需要节点和任务去进行解耦,解耦的代价是,需要共享资源,势必会带来写磁盘,不管是读磁盘还是写磁盘,相比 MPP 的通信方式来说显然会更慢。
3. 批处理&MPP 的互补
在实际使用中,两者其实是一个互补的关系,批处理速度慢,但是它的运行处理相对比较健壮,扩展性也比较好。适用于离线数据清洗。
MPP 的速度虽然相对较慢,且容量无法增大,每个部门相应的集群资源需要单独去搭建。适合于对清洗过的数据做交互式查询。
4. MPP on Hadoop
相对于互补的话,MPP on Hadoop 就不得不提一下,网易使用 Impala,还有相关的 presto 这些名字,在这里就把他们归类为 MPP on Hadoop 技术。MPP 技术它是 GREENPLUM,它的各个节点是传统关系型数据库 postgre。比如,刚才场景中是先批处理再 MPP,如果想用 GREENPLUM,需要将 Hadoop 中的数据导入到 GREENPLUM 中,因为它们底层的存储是不一样的,Hadoop 底层是 HDFS,而 GREENLUM 底层是 postgre,它们的存储上是没有关系的,必须要有一个导入的过程,正常来说 Hadoop 的生态,Hive 是一个常用的批处理技术,它的速度比较慢,为了加速计算,就诞生了 MPP on Hadoop 这样的技术。
这些技术大部分没有自己的存储,是一个类 MPP 的架构,需要控制节点把任务下发到对应的 MPP 的任务节点上,而在 MPP 节点的底层是 HDFS,等于是这两者的一个结合,实际运用起来查询会比 Hive 更快一些。
- 本文地址:阿里 | 优酷大数据 OLAP 技术选型
- 本文版权归作者和AIQ共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出
5. 预计算
讲到预计算,就不得不提到 Apache Kylin,它的架构如图,需要预先定义查询的内容。
比如说我要对某个 Key 进行计算,计算出 A 的数量,将其存在 Kylin 底下的 HBase,它的 Key 是某某维度等于 A,value 等于 A 的值,因为这个 Key 还可能等于 B,所以这个 B 的数据也存在 HBase 中,要达到这种情况,首先与 Kylin 之间一定要有一个交互式的协议,告诉它那些东西是我需要去查的,帮我做好计算。因为预计算中,当维度特别多的时候,是无法枚举所有要查询的东西,所以你要预先定义好 Kylin,这在 Kylin 中叫做 Cube,就是要定义你的 Cube 模型,告诉 Kylin 你的查询模式是怎么样的,而 Kylin 会根据定义的数据模型,去生成对应的 Hive 任务,Hive 任务会根据模型规则去完成计算,计算好之后写入 HBase 里,在 HBase 中每一个查询对应一个 Key,查询速度会很快。
这个方案绕过了大数据查询下会比较慢的问题,变成了一个 HBase 查询的问题,构建为 KV 数据存入 HBase 里,基本上可以达到一个亚秒级别的查询,MPP 的话当数据量比较大时,需要几十秒,使用 Kylin 基本上是一个亚秒级的 RT。但我们需要预先去定义一个数据模型,肯定会影响数据的灵活性。
比如播放的数据有没有发生卡顿,或者节点状况。我们在查询数据时,有分省份的查询,有分运营商的查询,要告诉 Kylin 要分省份的去查,分运营商的去查,还是需要省份和运营商交叉去查,如果没有明确,当临时的查询使用 Kylin 是达不到对应的效果的。业务上经常有变化,重新通过 Hive 去刷新任务,重新计算结果并写入 HBase,这本身就是一个非常费时费力的过程,是一个变化比较大的业务。另外再维度的复杂性上也是没有上限,比如十几个维度都要各自交叉,都要去交互到很深的话,这个模式其实是没有办法支持,它的预计算结果会膨胀的特别厉害,可能会比原来的数据还要多,这时就无法进行下去。
预计算还要介绍的是 druid,将其归类为预计算并不是特别明确,它有预计算的能力,当数据写入时,它有一个 roll-up 这样的配置,在第一步数据写入时会帮助你进行一个数据减少的工作,在它本身内部的架构里,它不是 Kylin 需要 HBase 这样的存储,druid 内部有一个自己的存储,专门针对 OLAP 进行了优化。druid 还是一个时序的存储,在时序上做优化,让老的数据存在老的存储里,新的数据存在新的存储里。在预计算和查询的灵活性方面,如果说只能够选择一套方案的话,可以考虑只使用 druid。
6. OLAP 方案综述
在这里将所说过的 OLAP 方案综述一下,将市面上的 OLAP 分为两种:
- 通过加并发的方式来解决问题:MPP 架构和批处理架构
- 通过预计算来解决问题
图中是市面上常见的 OLAP,纵向是不同的架构类型,横向是查询和存储的关系。
Kylin 可以说是一个计算框架,因为它底层的存储使用的是 HBase,用 Kylin 来解决数据如何建模的问题。
再往右就是 druid,它本身有预计算的能力是自建存储的。比如说美团做了一个 Kylin on druid 这样的工作,计算仍然是 Kylin,但是它把底层的 HBase 换成 druid,这样做的考虑将 druid 和 HBase 比较,实际在查询的能力方面还是要强不少的。
GREENPLUM 和 TiDB 或者 amazon 更偏向于传统架构,都是关系型的数据库,需要有自己的存储。
再往右就是基于 HDFS 的架构,HIVE 和 Spark 都是基础 HDFS 上做的批处理。
03 优酷不同业务场景的 OLAP 选型
1. 实战性场景
第一类场景是 API 与实时监控:API 是系统访问,比如在我们的推荐系统里,需要用到一些实时特征,如用户截至目前曝光了多少次,会存在非常大的 QPS,以及对 RT 要求很高,数据也要有分钟级的实时性要求。API 与实时监控,目前在优酷是自建的预计算系统。
为什么早期没有使用 Kylin,是因为实时 OLAP 当时支持较差。Kylin 和 Hive 还是有很强的依赖的。首先就是数据的收集,业界一般主要使用 kafka,这里使用类似 Kafka 这种消息队列,会把流式的信息导入进来,流计算使用 Flink,内部也存在 Cube 管理这样类似的协议,聚合得到和 Kylin 一样的 KV 结构数据,存储在阿里的表格存储里,和 HBase 差别比较小,然后用户去读取数据。
从思路上来说和 Kylin 差别不是很大,在预计算系统里面我们会提供一些网关服务,因为要对外提供 API,如果是报表的话也要根据报表平台来访问的,然后会有自己的查询引擎,解析类 SQL 这样的语法,把它解析成表格存储里面的数据。
另外也做了一块叫做维度计算,针对业务上变化速度快,也会尝试在 KV 结构上做计算,可能包括一些数学运算。
最后一个是维度字典,在实际使用中是非常重要的。比如版本的维度一直在变化,如果是在这样一个 HIVE 的平台里,可能使用 Groupby 可以查出具体版本,在将数据进行预计算后,存储在类似 HBase 的 KV 存储中。制作维度字典对应用性有比较好的提高,
2. BI 报表:批处理 +MPP
第二类是 BI 报表,是批处理 +MPP 组合的形式,其中对业务中的 RT 和 QPS 要求不高,重点在于需要支持非常复杂的分析,最好使用的方案其实是批处理 +MPP,批处理这层主要是进行数据清洗初步的聚合,如果是优酷的数据量,基本上是一分钟两分钟这种级别,速度上较慢。
通过对业务的理解,将关键的数据保留,通过批处理预先建好 DWS 层的模式处理,在这基础之上,往 MPP 的表中导入从而支持这个复杂的分析,底层的架构是一个离线的批处理的计算,批处理完成之后将数据放入离线的表中,并导入到阿里的数仓,使用 MPP 的数仓来支持,以及 BI 类工具来支持我们的业务需求,满足复杂分析的要求。
3. 实时 ad-hoc:类似 ELK
第三类场景是实时查询的一种场景,跟刚才的 BI 类又不相同,主要发生在优酷性能的统计数据里面,在这个场景下我们一般做预计算,但偏向实时的,分析比较复杂,通常适用于故障定位的场景。
比如如何去定位查找错误,查找机房存在问题,这都是一些比较常见的场景。这个场景对 RT 的要求较好。RT 和 QPS 方面没有 API 要求那么高,它的用户人数也不是那么多,没有一些高并发的场景,但是对数据的实时性和分析的复杂性还是存在要求的,这种的预计算也不大可能去满足,为解决这类问题,我们做的是一个类似 ELK 的方案。
首先是需要收集 log,在收集的过程中要做数据清洗,将数据存到 es 中,es 在大数据里面也是比较常用的,适用于故障排查的场景,搜索关键词、模糊搜索等。es 的聚合能力,过滤能力都是相对比较经典的。但确实模糊查询也没有很刻意的提出这个概念,甚至有些不支持模糊查询,比如说 Kylin,es 主打是模糊查询,但是 es 也实现了聚合功能,因为 es 里面是 JSON,JSON 里面某个字段,这个字段有多少 Key,聚合以后有多少个,这种它也是能够做的。而 join 就相对较差,它不是一个非常完备,但是在这种重聚合,过滤夹带一些模糊查询的的情况下,还是比较适合做一个引擎。在 es 后是一个 Kibana,但我们使用的不是 Kibana,是使用内部的 BI 工具。
在这种场景下,当错误发生了,我们可以很快的定位到错误位置,实现实时查询的能力。
注意:本文归作者所有,未经作者允许,不得转载