导语 |为了满足贝壳日益复杂、多样化业务场景下的多维数据分析需求,贝壳 OLAP 平台经历了从早期基 于Hive MySQL 原始阶段,到基于 Kylin单一引擎的平台化建设,再到支持多种不同OLAP引擎的灵活架构的发展历程。本文是对贝壳找房数据智能中心资深研发工程师——肖赞在腾讯云开发者社区沙龙online的分享整理,希望与大家一同交流。
一、贝壳业务背景介绍
贝壳找房的定位是科技驱动的新居住平台,提供涵盖二手房、新房、租赁、装修和社区服务多元化居住服务。贝壳找房聚合居住垂直品类服务商,提供全方位的品质居住服务,有三亿家庭用户,被认为是房产类的淘宝,很多品牌和开发商都入住了贝壳找房的平台。
贝壳找房推动了房产服务这个传统行业转向互联网化的过程,一方面要求业务运营日趋精益化,另一方面数据驱动角色的需求也不断增强。
贝壳找房的业务模式比较复杂,涉及到二手房、新房、装修、租赁等不同方向。这也给整个 OLAP 平台数据分析方面带来了很多挑战,比如如何更好的支持不同复杂业务场景下的需求。
二、OLAP 平台架构演化历程
OLAP 平台的架构发展大致可以分为三个阶段,第一个阶段是 2015 年到 2016 年链家网的时代,它是初期从无到有的阶段。第二个阶段是从 2016 年到 2019 年初,这个阶段是基于 Apache Kylin 构建的 OLAP 平台建设阶段。从 2019 年初到现在,迈入的是第三个阶段,灵活支持各种 OLAP 引擎的 OLAP 平台建设阶段,这个阶段结合了 OLAP 平台和 Kylin 平台的能力。
1. 第0阶段—Hive 2 MySQL 初期阶段
Hive 2 MySQL 之所以称之为 0 阶段,是因为还没有形成平台化,数据处理流程很简单。
数据经过Sqoop离线批量或 Kafka 实时进入大数据平台,处理后再通过常用的大数据调度系统每天定时写到关系型数据库 MySQL 中去,以此为基础构建各种报表。
这是从无到有的过程,很多公司最开始的阶段也是这样的方式,这种方式非常的简单很容易落地,把平台搭建起来就可以跑起来了。
但是其中的问题也很明显,受限于 MySQL 能力无法进行大数据量的快速存储和查询,对数据量百万、千万级别的系统很难支持,这种方式也缺乏共性能力的沉淀,整个需求定制的开发周期比较长。
因为这个阶段还称不上平台化,所以称之为 0 阶段。
初期阶段建立起来之后,随着用户去需求的增多,问题也逐渐暴露出来,这就需要对整个架构进行改造。
改造的目标很清晰,一是系统不支持快速查询和大量数据存储,需要平台针对这一点进行改进。二是平台化不够,这个阶段需要沉淀一些共性能力,能够建设公司级的 OLAP 平台。针对这两个问题,我们选择的是能够支持大数据量的 OLAP 引擎 Kylin。
对于平台化不够的问题,引入了中间层作为 OLAP 平台与用户统一的接口,于是有了第一阶段的 OLAP 平台架构。
2. 第 1 阶段—基于 Kylin 的 OLAP 平台架构
基于 Kylin 的 OLAP 平台架构共分为三层,首先是最底层的 OLAP 层,这一层是围绕 Apache Kylin 构建的 OLAP 平台,所以只有 Apache Kylin 这个引擎。
在此基础上引入指标平台层,它的主要作用是:一是它对外提供统一的 API;二是提供指标统一的定义和管理口径;三是实现指标查询。指
标平台层可以认为是应用层和 OLAP 引擎层之间的一个抽象,应用统一通过指标平台API来访问获取数据,而不直接访问OLAP引擎,并不暴露给上层业务而是通过主要平台API暴露给引擎。
指标平台引入抽象层到底是为了解决什么问题呢?
一是指标的定义,指标平台可以定义整个指标。首先明确什么是指标,很多公司谈到自己指标体系建设时候说,指标是业务单元细化和量化的度量层,使业务目标可描述可拆解,是量化项目的重要依据。
简单的说,数仓是通过维度建模包括新型和雪花型建模,里面会定义很多维度和度量。指标是对维度(星型)建模的抽象,把指标的维度和度量与新型模型对应,暴露给用户,用户可以根据某个指标就知道这个指标从哪些维度、哪些角度查询,知道有哪些度量。
例如,作为一家房产公司,我们定义的一个指标是“带看量”,这个指标支持很多个维度,可以查看不同运营管理大区的带看量。我们公司所有指标的定义管理都是在指标平台上进行的,不会存在歧义和口径不统一的问题。
各个业务方使用 OLAP 平台也是通过指标平台进行的,数据开发人员在 OLAP 平台上建指标,然后开放给业务方使用,来实现多维数据分析。
指标的第一个功能是统一的口径管理,第二是指标的查询,业务人员可以通过指标调用参数对指标的不同维度进行过滤。比如起始日期,指标平台根据调用参数自动转换成 Kylin 查询 SQL,对 Kylin 发起查询获得数据,并根据需求作进一步处理,例如同环比计算、指标间运算等。
指标平台的第三个功能是指标 API 应用,通过指标 API 对外暴露指标。指标API上层应用能够通过指标API来调用指标,比如公司的可视化平台,可以在里面配一个报表,可能很多公司也有这方面的可视化的工具,比如腾讯云也有可视化分析的工具。
选择指标后,对应的维度和度量也就明确了可以从哪些维度看,做哪些筛选,公司内部人员可以根据指标配置报表。
另一方面,也可以根据有些数据产品,比如贝壳为提高经纪人作业效率提供的店面管理、卖房情况等指标,这些数据产品可以通过API 调用指标获得指标数据,这就是指标API的应用。
为什么要选择 Kylin?
Apache Kylin 是由 eBay 开发者贡献到 Apache 开源社区的,可以满足较高并发的诉求,能够支持大规模数据查询,能够处理 TB 乃至 PB 级别的分析任务。
Kylin 的核心思想是预计算,对多维分析可能用到的度量进行预计算,将计算好的结果保存成 Cube,供之后查询。这样会缩短响应时间,也可以支持相对较高的并发。
Kylin 架构首先要求业务线定义一个“Cube”,需要用户指定有哪些维度和度量,之后就可以进行预计算了。Cube 构建完成后数据准备好就可以对外提供给用户查询了。
Kylin 的原理并不复杂,很多其他基于 OLAP 的引擎也是这么做的,只是之前没有应用大数据的基础设施,Kylin 是基于大数据平台构建的,可以支持更大的维度、数据量,以前的 OLAP 引擎有些计算是有限的。
Kylin 的预计算模式最大的问题是维度爆炸的问题,简单说就维度太多了,计算不过来了,Kylin 也提供了很多的技术来缓解这个问题。
在基于 Kylin 的 OLAP平台里面,对外统一的输出方式是指标。建指标的流程是数仓建模,确定业务过程生成任务表后创建 Cube,然后创建指标,在构建 Cube,最后进行指标的调用。
对已有的指标加以业务限定,也可以做复合指标,对于几个指标做四则运算可以得到新的指标。从整个流程上说,这个阶段基于Kylin的 OLAP 平台跟Cube是严格绑定的,整个过程 是在Kylin 上创建 Cube,然后在指标平台上创建指标。
这一套下来之后,在 2016 到 2019 年整个平台在公司内进行推广应用,指标也获得了广泛的应用,也建立起来整个公司指标体系,覆盖公司几乎所有的业务线。
现在整个公司有六千以上的指标,之前更多,最近进行了一些优化把一些不用的指标去除了,日均调用有两三千万。
平台构建完后在公司获得了广泛的应用,我们围绕 Kylin 做了很多工作,包括几个方面。
一是 Kylin 监控管理平台建设,Kylin 承载着综合指标,其中很多是关键指标,一出问题会影响整个作业,需要把监控管理构建好,及时看到各种问题可以解决。二是优化和定制服务;三是和整个公司大数据应用、公司大数据系统、原数据、调用系统进行整合。
主要是这三方面工作。Kylin 在贝壳有很大的应用量,高峰期整个企业有 800 多个 Cube,300 TB 以上的存储量、1600 亿行的数据,Cube 最大有 60 多亿,日均查询有两千万。
围绕 Kylin 构建的平台解决了公司的需求,但是并不是很完美,随着系统整个的应用推广业务要求也越来越高,也提出了很多问题。简单总结为以下几个方面:
首先是能力方面的问题,底层基于 Kylin 的预计算原理导致维度多、基数高,Kylin 的计算量就会指数型膨胀,它支持维度并不能太多,官方最多是80个,实际上20个以上就要深度优化了,支持维度也有限,我们的业务里面很多指标也有需要有三四十个维度,集团带看量就有20个维度。
业务变化很快,也需要快速建立指标,快速对指标维度进行变更,这对 Kylin 以预计算为核心原理的引擎来说是比较麻烦的事。
因为重新构建整个 Cube 耗时很长,维度多、数据量大。维度变也要把整个指标所有的 Cube 全部重新预计算一遍,一个维度变更几天、几周、上月也有的,无法满足快速业务迭代的需求。
其次是性能方面的问题,Cube 构建的时候就要指定一个HBase的RowKey,如果一般的数据开发人员、业务开发人员不了解HBase,就会导致他建立的 Cube 性能差,就需要 OLAP 的维护人员去帮助进行优化。
还有一些其他的问题,比如在数仓里面碰到的一些经典问题,维度的缓慢变化、多值维度(例如一个CA管理多个店,一个店被多个CA管理,多对多关系)。
究其原因,很多都是由于 Kylin 本身的原理导致了这些问题,单一 OLAP 引擎(Kylin)是无法满足公司各种场景需求的,为了让针对不同的业务场景的用户方使用不同的 OLAP 引擎,OLAP 平台也要做出相应的改动。
3. 第 2 阶段—支持多种 OLAP 引擎的 OLAP 平台
新的架构底下一层是 OLAP 引擎,这一层除了 Kylin 以外也可以引入其他引擎。在 OLAP 引擎之上是一个查询引擎 QE,对指标平台统一架构上提供查询接口,承担屏蔽底层 OLAP 引擎查询语句差异的工作,让指标平台的架构更加清晰。
之前基于 Kylin 构建的 OLAP 平台,应用层不直接依赖于底层引擎Kylin,而是通过指标API来调用,这样底下的引擎可的变化可以做到用户是无感知的,这就是提供抽象层的好处。
接口不变用户上层应用不需要改变,底层的改变是OLAP平台内部的事情。这种方式可以支持多种OLAP引擎,应用接口也保持一致,不需要用户做改动。
指标平台层最大的改变是 Cube 管理,不再依赖于Kylin。如果指标要映射到 Kylin中,会转变成 Kylin 的 Cube。整个 Cube 的定义也参考了 Kylin,Cube 相当于在指标平台层和底层 OLAP 引擎之间又引入了一个抽象层。需要查询的时候可以将 Cube 和 OLAP 进行动态绑定。
查询引擎层主要是用于屏蔽,向上提供统一的数据查询接口,用来屏蔽底层 OLAP 引擎的差异,实现统一查询请求到对应 OLAP 引擎的转换。
这种架构引擎下,标准化开发流程的步骤没有太大差别,还是数仓建模、创建 Cube、创建指标、构建 Cube、调用指标,但是所有动作都是在指标平台上完成。但是很多动作语义发生了变化,构建 Cube 是对 Druid/CK/Doris 完成数据的导入。
三、OLAP 引擎选型与实践
1. OLAP 选型要关注什么?
OLAP 选型一般关注三个方面,一是是它支持的数据量是怎样的,比如 TB 级甚至更大。二是性能,性能有两方面,一是响应时间快不快,二是支持并发度,在高 QBS 的情况下整个查询的性能怎么样。
第三是灵活性,灵活性是没有标准的,根据应用的需求定义灵活性,常见的 OLAP 引擎是否支持实时导入、实时更新、实时动态变更等等,这些都是灵活性的体现,具体需要哪些是根据自己的应用需求来定义的。
了解这些标准之后我们看一下常见的开源 OLAP 引擎,开源 OLAP 引擎有十几二十种,没有一个引擎能把它们都统一了。我们对它们进行了一个大概的分类,分类原则一是看它的原理是怎样的,第二看是否有自定义的存储格式,能管理自己的数据。
2. OLAP 引擎有哪几种?
OLAP 引擎大概可以分为三类,首先是 SQL on Hadoop,特点是数据量大、容错性好、灵活性高,有完备的 SQL 语句支持,但性能上要达到亚秒级响应是比较困难的。
第二类基于 MPP 的,特点是不自己管理存储,使用通用的存储格式,在并发量大的时候性能下降也是比较快的。第三类有自己的存储格式,比如典型的 Druid、CK,一般这种类型的引擎支持的数据量相对较大,灵活性上各个引擎的差异性比较大。
3. OLAP 引擎的比较
从我们自己的工作需求来说,需要有亚秒级的响应、比较高的并发和QBS,对我们来说在指标平台是只能选择第三类的。我们现在现在使用的是 Kylin,基于这个原则我们考察了三种引擎,Druid、CK 和 Doris。
我们首先关注的是数据支持量和查询性能,这几个数据都是不错的,可以满足公司 TB 级的需求,并发量相对高,其他关注的几个是实时数据导入和更新等等,目前 Doris 支持的比较好一点,ClickHouse虽然也支持实时更新,但比较弱。
另外对 Online 的支持就需要 Schema 灵活的变更。Druid 我们现在的应用的还是比较多,承担了 20%-30% 的量。
4. Apache Druid
Apache Druid 是 MetaMarket 公司开发的,然后贡献给 Apache,它有以下几个特点:
- 支持海量数据;
- 亚秒级查询响应:列式存储;
- 高可用性、可伸缩;
- 并行处理:Scatter&Gather 模式;
- 支持实时导入;
- 灵活数据模式 Schema-less。
从它的架构来看,有三个节点,查询节点、数据节点和 Master 节点。查询节点用来查询请求,查询请求到了 Broker 上后找到对应的 Historical,对应之后传给客户端。数据节点用来存放数据, 通过 Deep storage 进行深度存储,自己不做同步副本的事情。
Apache Druid 在数据格式上分成三个部分:
- Timestamp:时间戳信息;
- Dimension:维度信息;
- Metrics:一般是数值型。
Apache Druid 对数据模型有强要求,首先是时间戳,这是用来做分区的;二是维度,Dimension 来过滤条件,也可以做聚合。
它的原理是根据时间来分区,每个区叫做一个 Chunk,然后根据数据量的大小又可以分成一个或多个 Ssegment 文件。Ssegment 是自定义的列式存储格式,对查询比较优化,对 OLAP 引擎是比较友好的。
目前 Druid 主要用于离线指标,实时指标还在测试,大概承担了平台 30% 的流量,性能还不错,3s 的返回大概在 99.7%。
Kylin Cube 构建和 Druid 数据导入时长比较:
我们使用 Druid 是为了解决 Cube 构建时间太长的问题。
我们构建一个 Cube 需要 220 分钟,但我们导入 Druid 只需要 22 分钟,也就是说如果 OLAP 表大概早上六点好的话,构建 Cube 要等到九点才能查询指标,而 Druid 大概六点半就可以查了。同样,如果我要回刷一年的数据,用 Kylin 可能要很久,用 Cube 可能就很快。
Kylin 与 Druid 相较源数据的膨胀率:
Druid 一般数据量比较小,Kylin 根据维度和基数密切相关,最大的数据膨胀率达到了 139%。
Druid 相关工作:
(1)Druid 监控管理平台建设
(2)Druid 优化与定制改造
- Druid 精确去重功能支持
- Druid 大查询监控与处理
- Druid 数据导入优化
- 查询优化
(3)Druid 与公司内部大数据系统的整合
5. Clickhouse/Apache Doris
CK 和 Doris 就不过多介绍了,都是基于 MPP 的,有自定义的存储格式。目前主要用于实时指标和明细数据查询,承担了小部分流量,在 1%-2% 左右,现在还在进一步深度测试中。
四、未来工作规划
现在我们整个平台的基本架构已经确定了,引入了很多引擎,正在把各个引擎推广应用,根据之后推广应用的情况会收缩到一两种引擎做比较深度的定制。
第二就是希望能够在多个 OLAP 引擎之间做自动的路由,性能比较差的时候自动路由到另一个引擎。
另外就是需要与 Adhoc 平台的融合,还有实时指标的优化,目前实时指标只是基本上把整个流程走通了,引入这个引擎后如何更好的支持实时指标这是后续需要做的工作。
五、Q&A
Q:维度变化你们常用的方案是什么,拉链表吗?
A:对,我们现在是用拉链表,但是像 Kylin 这些维度变化我们事先用大宽表把维度打进去,查的时候会把拉链表对应的信息查出来加到里面去。
Q:对查询引擎感兴趣,能介绍下如何屏蔽 SQL 方面的差异吗?
A:我们对外统一定义结构化场景语言,指标平台只要通过统一的语句过来,内部会分析更多引擎的差异,看怎么把统一的语句转换成对应的引擎差异,这个事情是在 QE 查询引擎里面做的。
Q:实时性差的问题如何处理?
A:实时指标的实时性并不会差,像 Druid 和 Doris 是可以从 Kafka 实时接入数据,如果实时数据生产流程没有延时的话它的实时性是可以保证的。
Q:OLAP 查询平台的并发量?
A:并发量最高的 QPS 在两三千吧。
Q:不同 OLAP 引擎查询速度差距大如何保证性能?
A:需要分析查询比较差的那个指标更适合哪个引擎,比如在 Druid 上查询比较差是什么原因,是不是更适合另外一种引擎,那就把它迁移到另一种引擎上,就是希望找到更适合的场景。
Q:有没有用 Cassandra 做底层存储平台?
A:它和 HBase 类似,如果用来做底层存储还需要做一些工作,在 OLAP 里面用的还不多。像 HBase ,它是在 Kylin 底层用来做 Cube 存储,Kylin 4.0 也在剥离对 HBase 的依赖,因为它并不是列式存储的方式。