Kylin是什么
今天,随着移动互联网、物联网、AI等技术的快速兴起,数据成为了所有这些技术背后最重要,也是最有价值的“资产”。如何从数据中获得有价值的信息?这个问题驱动了相关技术的发展,从最初的基于文件的检索、分析程序,到数据仓库理念的诞生,再到基于数据库的商业智能分析。而现在,这一问题已经变成了如何从海量的超大规模数据中快速获取有价值的信息,新的时代、新的挑战、新的技术必然应运而生。
在大数据处理技术领域,用户最普遍的诉求就是希望以很简易的方式从大数据平台上快速获取查询结果,同时也希望传统的商务智能工具能够直接和大数据平台连接起来,以便使用这些工具做数据分析。目前已经出现了很多优秀的SQL on Hadoop引擎,包括Hive、Impala及 SparkSQL等,这些技术的出现和应用极大地降低了用户使用Hadoop平台的难度。
为了进一步满足“在高并发、大数据量的情况下,使用标准SQL查询聚合结果集能够达到毫秒级”这一应用场景,Apache Kylin应运而生,在 eBay孵化并最终贡献给开源社区。Apache Kylin是2013年由eBay 在上海的一个中国工程师团队发起的、基于Hadoop大数据平台的开源 OLAP引擎,它采用多维立方体预计算技术,利用空间换时间的方法,把很多分钟级别乃至小时级别的大数据查询速度一下子提升到了亚秒级别,极大地提高了数据分析的效率,填补了业界在这方面的空白。该引擎为超大规模数据集上的交互式大数据分析打开了大门。
2 为什么要用Kylin
自从Hadoop诞生以来,大数据的存储和批处理问题均得到了妥善解决,而如何高速地分析数据也就成为了下一个挑战。于是各式各样的“SQL on Hadoop”技术应运而生,其中以Hive为代表,Impala、Presto、 Phoenix、Drill、SparkSQL等紧随其后。它们的主要技术是“大规模并行处理”(Massive Parallel Processing,MPP)和“列式存储”(Columnar Storage)。 大规模并行处理可以调动多台机器一起进行并行计算,用线性增加的资源来换取计算时间的线性下降。列式存储则将记录按列存放,这样做不仅可以在访问时只读取需要的列,还可以利用存储设备擅长连续读取的特点,大大提高读取的速率。这两项关键技术使得Hadoop上的SQL查询速度从小时提高到了分钟。
然而分钟级别的查询响应仍然离交互式分析的现实需求还很远。分析师敲入查询指令,按下回车,还需要去倒杯咖啡,静静地等待查询结果。得到结果之后才能根据情况调整查询,再做下一轮分析。如此反复, 一个具体的场景分析常常需要几小时甚至几天才能完成,效率低下。 这是因为大规模并行处理和列式存储虽然提高了计算和存储的速度,但并没有改变查询问题本身的时间复杂度,也没有改变查询时间与数据量成线性增长的关系这一事实。假设查询1亿条记录耗时1分钟,那么查询10亿条记录就需10分钟,100亿条记录就至少需要1小时40分钟。 当然,可以用很多的优化技术缩短查询的时间,比如更快的存储、更高效的压缩算法,等等,但总体来说,查询性能与数据量呈线性相关这一点是无法改变的。虽然大规模并行处理允许十倍或百倍地扩张计算集群,以期望保持分钟级别的查询速度,但购买和部署十倍或百倍的计算集群又怎能轻易做到,更何况还有高昂的硬件运维成本。
另外,对于分析师来说,完备的、经过验证的数据模型比分析性能更加重要,直接访问纷繁复杂的原始数据并进行相关分析其实并不是很友 好的体验,特别是在超大规模的数据集上,分析师将更多的精力花在了等待查询结果上,而不是在更加重要的建立领域模型上。
3 Kylin怎样解决关键问题
Apache Kylin的初衷就是要解决千亿条、万亿条记录的秒级查询问题,其中的关键就是要打破查询时间随着数据量成线性增长的这个规律。仔细思考大数据OLAP,可以注意到两个事实。
- 大数据查询要的一般是统计结果,是多条记录经过聚合函数计算后的统计值。原始的记录则不是必需的,或者访问频率和概率都极低。
- 聚合是按维度进行的,由于业务范围和分析需求是有限的,有意义的维度聚合组合也是相对有限的,一般不会随着数据的膨胀而增长。
基于以上两点,我们可以得到一个新的思路——“预计算”。应尽量多地预先计算聚合结果,在查询时刻应尽量使用预算的结果得出查询结果,从而避免直接扫描可能无限增长的原始记录。
举例来说,使用如下的SQL来查询10月1日那天销量最高的商品:
select item,sum(sell_amount)
from sell_details
where sell_data=’2016-10-1’
group by item
order by sum(sell_amount) desc;
用传统的方法时需要扫描所有的记录,再找到10月1日的销售记录,然后按商品聚合销售额,最后排序返回。假如10月1日有1亿条交易,那么 查询必须读取并累计至少1亿条记录,且这个查询速度会随将来销量的增 加而逐步下降。如果日交易量提高一倍到2亿,那么查询执行的时间可能 也会增加一倍。
而使用预计算的方法则会事先按维度[sell_date,item]计算 sum(sell_amount)并存储下来,在查询时找到10月1日的销售商品就可以直接排序返回了。读取的记录数最大不会超过维度[sell_date,item]的组 合数。显然这个数字将远远小于实际的销售记录,比如10月1日的1亿条 交易包含了100万条商品,那么预计算后就只有100万条记录了,是原来的百分之一。并且这些记录已经是按商品聚合的结果,因此又省去了运 行时的聚合运算。从未来的发展来看,查询速度只会随日期和商品数目 的增长而变化,与销售记录的总数不再有直接联系。假如日交易量提高 一倍到2亿,但只要商品的总数不变,那么预计算的结果记录总数就不会 变,查询的速度也不会变。
“预计算”就是Kylin在“大规模并行处理”和“列式存储”之外,提供给 大数据分析的第三个关键技术。
4 Kylin的工作原理
Apache Kylin的工作原理本质上是MOLAP(Multidimensional Online Analytical Processing)Cube,也就是多维立方体分析。这是数据分析中相当经典的理论,在关系数据库年代就已经有了广泛的应用,下面将对其做简要介绍。
4.1 维度和度量简介
在说明MOLAP Cube之前需要先介绍一下维度(Dimension)和度量 (Measure)这两个概念。 简单来讲,维度就是观察数据的角度。比如电商的销售数据,可以从时间的维度来观察(如图1-2的左侧所示),也可以进一步细化,从时间和地区的维度来观察(如图1-2的右侧所示)。维度一般是一组离散的值,比如时间维度上的每一个独立的日期,或者商品维度上的每一件独立的商品。因此统计时可以把维度值相同的记录聚合在一起,然后应用聚合函数做累加、平均、去重复计数等聚合计算。
度量就是被聚合的统计值,也是聚合运算的结果,它一般是连续的值,如图1-2中的销售额,抑或是销售商品的总件数。通过比较和测算度量,分析师可以对数据进行评估,比如今年的销售额相比去年有多大的增长,增长的速度是否达到预期,不同商品类别的增长比例是否合理等。
4.2 Cube和Cuboid
有了维度和度量,一个数据表或数据模型上的所有字段就可以分类了,它们要么是维度,要么是度量(可以被聚合)。于是就有了根据维度和 度量做预计算的Cube理论。
给定一个数据模型,我们可以对其上的所有维度进行组合。对于N个维度来说,组合的所有可能性共有2N种。对于每一种维度的组合,将度量做聚合运算,然后将运算的结果保存为一个物化视图,称为Cuboid。所有维度组合的Cuboid作为一个整体,被称为Cube。所以简单来说,一个 Cube就是许多按维度聚合的物化视图的集合。
下面来列举一个具体的例子。假定有一个电商的销售数据集,其中维度包括时间(Time)、商品(Item)、地点(Location)和供应商(Supplier), 度量为销售额(GMV)。那么所有维度的组合就有2 4 =16种(如图1-3所 示),比如一维度(1D)的组合有[Time]、[Item]、[Location]、[Supplier]4种; 二维度(2D)的组合有[Time,Item]、[Time,Location]、[Time、Supplier]、 [Item,Location]、[Item,Supplier]、[Location,Supplier]6种;三维度(3D)的 组合也有4种;最后零维度(0D)和四维度(4D)的组合各有1种,总共就有 16种组合。
计算Cuboid,即按维度来聚合销售额。如果用SQL语句来表达计算 Cuboid[Time,Loca-tion],那么SQL语句如下:
Select Time,Location,Sum(GMV) as GMV from Sales group by Time,Location
将计算的结果保存为物化视图,所有Cuboid物化视图的总称就是 Cube。
4.3 工作原理
Apache Kylin的工作原理就是对数据模型做Cube预计算,并利用计算的结果加速查询,具体工作过程如下。
1)指定数据模型,定义维度和度量。
2)预计算Cube,计算所有Cuboid并保存为物化视图。
3)执行查询时,读取Cuboid,运算,产生查询结果。
由于Kylin的查询过程不会扫描原始记录,而是通过预计算预先完成 表的关联、聚合等复杂运算,并利用预计算的结果来执行查询,因此相比 非预计算的查询技术,其速度一般要快一到两个数量级,并且这点在超 大的数据集上优势更明显。当数据集达到千亿乃至万亿级别时,Kylin的 速度甚至可以超越其他非预计算技术1000倍以上。
5 Kylin的技术架构
Apache Kylin系统可以分为在线查询和离线构建两部分,技术架构如图1-4所示,在线查询的模块主要处于上半区,而离线构建则处于下半区。
我们首先来看看离线构建的部分。从图1-4可以看出,数据源在左侧,目前主要是Hadoop Hive,保存着待分析的用户数据。根据元数据的定义,下方构建引擎从数据源抽取数据,并构建Cube。数据以关系表的形式输入,且必须符合星形模型(Star Schema)(更复杂的雪花模型在成文时块做任意的扩展和替换。Kylin的三大依赖模块分别是数据源、构建引擎和存储引擎。在设计之初,作为Hadoop家族的一员,这三者分别是Hive、 MapReduce和HBase。但随着推广和使用的深入,渐渐有用户发现它们均存在不足之处。比如,实时分析可能会希望从Kafka导入数据而不是从 Hive;而Spark的迅速崛起,又使我们不得不考虑将MapReduce替换为Spark,以期大幅提高Cube的构建速度;至于HBase,它的读性能可能还不如Cassandra或Kudu等。可见,是否可以将一种技术替换为另一种技术已成为一个常见的问题。Kylin系统架构进行了重构,将数据源、构建引擎、存储引擎三大依赖抽象为接口,而Hive、 MapReduce、HBase只是默认实现。深度用户可以根据自己的需要做二次开发,将其中的一个或多个替换为更适合的技术。
这也为Kylin技术的与时俱进埋下了伏笔。如果有一天更先进的分布式计算技术取代了MapReduce,或者更高效的存储系统全面超越了HBase,Kylin可以用较小的代价将一个子系统替换掉,从而保证Kylin能够紧跟技术发展的最新潮流,从而保持最高的技术水平。可扩展架构也带来了额外的灵活性,比如,它可以允许多个引擎同时并存。例如Kylin可以同时对接Hive、Kafka和其他第三方数据源;抑或用户可以为不同的Cube指定不同的构建引擎或存储引擎,以期达到最极致的性能和功能定制。
6 Kylin的主要特点
Apache Kylin的主要特点包括支持SQL接口、支持超大数据集、秒级 响应、可伸缩性、高吞吐率、BI工具集成等。
6.1 标准SQL接口
Apache Kylin以标准SQL作为对外服务的主要接口。因为SQL是绝大多数分析人员最熟悉的工具,同时也是大多数应用程序使用的编程接口。尽管Kylin内部以Cube技术为核心,对外却没有选用 MDX(MultiDimensional eXpressions)作为接口。虽然MDX作为OLAP查询语言,从学术上来说,它是更加适合Kylin的选择,然而实践表明,SQL简单易用,代表了绝大多数用户的第一需求,这也是Kylin能够快速推广的 一个关键。
SQL需要以关系模型作为支撑。Kylin使用的查询模型是数据源中的 关系模型表,一般而言,也就是指Hive表。终端用户只需要像原来查询 Hive表一样编写SQL,就可以无缝地切换到Kylin,几乎不需要额外的学习,甚至原本的Hive查询也因为与SQL同源,大多都无须修改就能直接在 Kylin上运行。 Apache Kylin在将来也可能会推出MDX接口。事实上已经有方法可 以通过MDX转SQL的工具,让Kylin也能支持MDX。
6.2 支持超大数据集
Apache Kylin对大数据的支撑能力可能是目前所有技术中最为领先的。早在2015年eBay的生产环境中Kylin就能支持百亿记录的秒级查询, 之后在移动的应用场景下又有了千亿记录秒级查询的案例。这些都是实 际场景的应用,而非实验室中的理论数据。
因为使用了Cube预计算技术,在理论上,Kylin可以支撑的数据集大小没有上限,仅受限于存储系统和分布式计算系统的承载能力,并且查询速度不会随数据集的增大而减慢。Kylin在数据集规模上的局限性主要在于维度的个数和基数。它们一般由数据模型来决定,不会随着数据规模的增长而线性增长,这也意味着Kylin对未来数据的增长有着更强的适 应能力。
对于Apache Kylin,除了eBay将其作为孵化公司有广泛应用之外,国内外一线的互联网公司对此几乎都有大规模的 使用,包括百度、网易、京东、美团、唯品会、Expedia等。此外,其在传统 行业中也有非常多的实际应用,包括中国移动、银联、国美等。据不完全 统计,真实上线的Apache Kylin用户已经超过了一百多家,在开源后一年多一点的时间内能有如此大的全球用户基础,足见Kylin在处理超大规模 数据集上的能力和优势。
6.3 亚秒级响应
Apache Kylin拥有优异的查询响应速度,这点得益于预计算,很多复杂的计算,比如连接、聚合,在离线的预计算过程中就已经完成,这大大降低了查询时刻所需要的计算量,提高了响应速度。
根据可查询到的公开资料可以得知,Apache Kylin在某生产环境中 90%的查询可以在3s内返回结果。这并不是说一小部分SQL相当快,而是在数万种不同SQL的真实生产系统中,绝大部分的查询都非常迅速;在另外一个真实的案例中,对1000多亿条数据构建了立方体,90%的查询性能 都在1.18s以内,可见Kylin在超大规模数据集上表现优异。这与一些只在实验室中,只在特定查询情况下采集的性能数据不可同日而语。当然并不是使用Kylin就一定能获得最好的性能。针对特定的数据及查询模式,往往需要做进一步的性能调优、配置优化等,性能调优对于充分利用好 Apache Kylin至关重要。
6.4 可伸缩性和高吞吐率
在保持高速响应的同时,Kylin有着良好的可伸缩性和很高的吞吐 率。图1-5是来自网易的性能分享。图1-5中左侧是Kylin查询速度与 Mondrian/Oracle的对比,可以看到在3个测试查询中,Kylin分别比 Mondrian/Oracle快147倍、314倍和59倍。
同时,图1-5中右侧展现了Kylin的吞吐率及其可伸缩性。在只有1个 Kylin实例的情况下,Kylin每秒可以处理近70个查询,已经远远高于每秒 20个查询的一般水平。更为理想的是,随着服务器的增加,吞吐率也呈线性增加,存在4个实例时可达到每秒230个查询左右,而这4个实例仅部署在一台机器上,理论上添加更多的应用服务器后可以支持更大的并发率。这主要还是归功于预计算降低了查询时所需的计算总量,令Kylin可 以在相同的硬件配置下承载更多的并发查询。
6.5 BI及可视化工具集成
Apache Kylin提供了丰富的API,以与现有的BI工具集成,具体包括如下内容。
- ODBC接口,与Tableau、Excel、Power BI等工具集成。
- JDBC接口,与Saiku、BIRT等Java工具集成。
- Rest API,与JavaScript、Web网页集成。
分析师可以沿用他们最熟悉的BI工具与Kylin一同工作,或者在开放 的API上做二次开发和深度定制。
另外,Kylin核心开发团队也贡献了Apache Zeppelin的插件,现在已经可以用Zeppelin来访问Kylin服务。
6.6 与其他开源产品比较
与Apache Kylin一样致力于解决大数据查询问题的其他开源产品也 有不少,比如Apache Drill、Apache Impala、Druid、Hive、 Presto(Facebook)、SparkSQL等。本节试图将Kylin与它们做一个简单的比较。 从底层技术的角度来看,这些开源产品有很大的共性,一些底层技 术几乎被所有的产品一致采用,Kylin也不例外。
- 大规模并行处理:可以通过增加机器的方式来扩容处理速度,在相同的时间里处理更多的数据。
- 列式存储:通过按列存储提高单位时间里数据的I/O吞吐率,还能跳过不需要访问的列。
- 索引:利用索引配合查询条件,可以迅速跳过不符合条件的数据块,仅扫描需要扫描的数据内容。
- 压缩:压缩数据然后存储,使得存储的密度更高,在有限的I/O速率下,在单位时间里读取更多的记录。
综上所述,我们可以注意到,所有这些方法都只是提高了单位时间内处理数据的能力,当大家都一致采用这些技术时,它们之间的区别将只停留在实现层面的代码细节上。最重要的是,这些技术都不会改变一个事实,那就是处理时间与数据量之间的正比例关系。当数据量翻倍时,MPP(在不扩容的前提下)需要翻倍的时间来完成计算;列式存储需要翻倍的存储空间;索引下符合条件的记录数也会翻倍;压缩后的数据大小也还是之前的两倍。因此查询速度也会随之变成之前的两倍。当数据量成 十倍百倍地增长时,这些技术的查询速度就会成十倍百倍地下降,最终变得不能接受。
Apache Kylin的特色在于,在上述的底层技术之外,另辟蹊径地使用了独特的Cube预计算技术。预计算事先将数据按维度组合进行了聚合,将结果保存为物化视图。经过聚合,物化视图的规模就只由维度的基数来决定,而不再随着数据量的增长呈线性增长。以电商为例,如果业务扩张,交易量增长了10倍,只要交易数据的维度不变(供应商/商品数量不 变),聚合后的物化视图将依旧是原先的大小,查询的速度也将保持不变。
与那些类似产品相比,这一底层技术的区别使得Kylin从外在功能上 呈现出了不同的特性,具体如下。
- SQL接口:除了Druid以外,所有的产品都支持SQL或类SQL接口。巧合的是,Druid也是除了Kylin以外,查询性能相对更好的一个。这点除了 Druid有自己的存储引擎之外,可能还得益于其较为受限的查询能力。
- 大数据支持:大多数产品的能力在亿级到十亿级数据量之间,再大 的数据量将显著降低查询的性能。而Kylin因为采用预计算技术,因此查询速度不受数据量限制。有实际案例证明数据量在千亿级别时,Kylin系 统仍然能够保有秒级别的查询性能。
- 查询速度:如前文所述,一般产品的查询速度都会不可避免地随着 数据量的增长而下降,而Kylin则能够在数据量成倍增长的同时,查询速度保持不变,而且这个差距也将随着数据量的成倍增长而变得愈加明显。
- 吞吐率:根据之前的实验数据,Kylin的单例吞吐量一般在每秒70个 查询左右,并且可以线性扩展,而普通的产品因为所有计算都在查询时 完成,所以需要调动集群的更多资源才能完成查询,通常极限在每秒20个查询左右,而且扩容成本较高,需要扩展整个集群。相对的,Kylin系统 因为瓶颈不在整个集群,而在于Kylin服务器,因此只需要增加Kylin服务器就能成倍地提高吞吐率,扩容成本低廉。
7 小结
本章介绍了Apache Kylin的历史背景和技术特点。尤其是它基于预计 算的大数据查询原理,理论上可以在任意大的数据规模上达到O(1)常数 级别的查询速度,这一点也是Apache Kylin与传统查询技术的关键区别, 传统技术,如大规模并行计算和列式存储的查询速度都在 O(N)级别,与数据规模增线性关系。如果数据规模增长10倍,那么O(N) 的查询速度就会下降到十分之一,无法满足日益增长的数据需求。依靠 Apache Kylin,我们不用再担心查询速度会随着数据量的增长而减慢,面对未来的数据挑战时也能更有信心。