OLAP开源引擎对比之历史概述
OLAP概念诞生于1993年,工具则出现在更早以前,有史可查的第一款OLAP工具是1975年问世的Express,后来走进千家万户的Excel也可归为此类,所以虽然很多数据人可能没听过OLAP,但完全没打过交道的应该很少。
这个概念主要是在大数据圈里流传,而在大数据领域里,目前主流的OLAP开源引擎都诞生于2006年以后,那一年hadoop横空出世,而后大数据分析的各种方法论和引擎也随之兴起。
本系列主要介绍Hive、Spark SQL、Presto、Kylin、Impala、Druid、Clickhouse、Greenplum、StarRocks,并不代表全部,但确实是国内大数据分析领域内应用最广的几款开源引擎。
本系列将涉及历史、架构、部署运维,以及优化器、物化视图等多个宏观和微观维度,希望能帮助大家对OLAP引擎建立比较直观的了解。
开篇先讲一讲历史。
Hive
讲Hive的历史之前,简单说一下为什么要谈历史。历史的一个重要特征是局限性,就软件技术而言,回归到过去的软硬件环境,理解当时存在的局限性,才更能理解一款代时代产品的意义。
Hive由facebook开发于2007年,其历史背景是,2006年开源的hadoop虽然强大,但并不好用,作为核心组件之一的Mapreduce是一个编程框架,数据分析师需要写java代码才能实现查询需求,相比于能够轻松上手的SQL,这种模式将很多人拦在了门外。
facebook开发Hive的初衷,正是为了应对这一问题,希望能让非专业人士也能轻松地查询和分析存储在Hadoop集群中的海量数据。
不考虑工程复杂性,拿到这个需求后你的开发思路是怎样的?会不会想着写一套转译工具,将容易上手的SQL翻译成有一定门槛的Mapreduce代码,然后下发给hadoop集群去执行?
大体上,初期的Hive也确实是这么干的,其支持的HiveSQL跟大家所熟悉的SQL很像,编译器本质上干的就是翻译的活儿。
后来Spark问世,Hive开始支持Spark作为计算引擎,性质也是一回事,就是将HiveSQL翻译成Spark计算程序,扔给Spark去执行。
不同于Mapreduce直接基于原始数据进行计算,Hive在实际使用中是有建表环节的,从原始数据提取、转换结构化数据到表中,后续的查询也基于表内数据来计算,而表本身也存储于hdfs。
Spark SQL
Spark于2009年诞生于伯克利大学AMPLab,开源于2010年。如果说Hive首先要解决的是Mapreduce的易用性问题,那么Spark的第一优先目标是解决Mapreduce性能不给力的问题。
在Mapreduce诞生的时候,内存还比较昂贵,这决定了Mapreduce在设计上非常注重对内存的节省,多任务串联时,中间结果会进行落盘,结果就是导致大量的I/O操作,性能受到严重制约。
具体来看,设想一个查询涉及到两个Mapreduce任务,即job1、job2,其中job2的输入依赖于job1的输出,在运行中,job1的输出会先持久化到硬盘中,轮到job2执行时,则需要重新从硬盘中读取job1的输出结果。 不难想到,如果job1的输出结果并不落盘,只保留在内存中,而job2直接从内存中读取job1的输出结果进行计算,整个过程显然会高效得多。
Spark 的 DAG 和 RDD 即很好地实现了这一点,DAG 记录了 Job 的 Stage 以及在 Job 的执行过程中父 RDD 和子 RDD 之间的依赖关系,中间结果能够以 RDD 的形式存放在内存中,并且能够从 DAG 中恢复,从而大大减少了磁盘 I/O。
当然,DAG 和 RDD 的原理和意义远不止于此,减少的不仅是落盘,还包括shuffle,这里不展开讨论。
如今的Spark已拥有一系列高级工具,包括Spark SQL、MLlib、GraphX和Spark Streaming,不能完全以性能来概括其优势,但其早期崛起,凭借的确实是远胜于Mapreduce的优异性能。
说回到Spark SQL,前身Shark是Spark0.x版的时候推出的一套工具,底层使用Spark的基于内存的计算模型,性能上比Hive提升了很多倍,在Spark 1.x时Shark被淘汰,后来重点就放到了 Spark SQL 上。
Spark SQL的源码就在Spark内,与Spark Core无缝集成,是Spark程序优化、执行的核心组件,在使用上你可以将它对比Hive来理解,本质上是将SQL编译成Spark程序去执行,另外Spark SQL在设计时就考虑到了与Hive的兼容性,支持Hive的很多特性。
Presto
Presto也是由facebook开发并开源,问世时间为2012年,即Hive问世的5年后、Spark开源的2年后。
跟Spark一样,Presto的出现也是为了解决Mapreduce存在的性能问题,早期facebook依赖Hive做数据分析,前面提过,Hive底层依赖MapReduce,而MapReduce由于大量的I/O操作导致性能受到制约,据说facebook也曾调研过其它引擎,但鉴于facebook的数据规模和复杂场景,并没有找到合意的,所以索性重新造了轮子。
Presto和Spark SQL都是MPP架构,都是基于内存计算,不过Presto是纯粹的查询引擎,没有自己的存储,当出现内存不足时Spark会落地到磁盘,Presto则可能导致内存溢出。
Presto最初是为hadoop开发的,但后来支持的数据源不断增加,早就不限于hadoop生态,用户可以使用熟悉的SQL语法查询Hive、Cassandra、PostgreSQL、Kafka、MySQL、ElasticSearch 等数据,统一查询也成为Presto的重要特性。
Kylin
Kylin由eBay中国团队于2013年开始开发,2014年上线,并于同年开源,是国人主导的一款重量级OLAP引擎。
前面提到的Hive、Spark SQL、Presto都属于ROLAP,Kylin则是一款MOLAP产品,基本原理是对数据模型做Cube预计算,并利用计算的结果加速查询。
使用时,需要提前从Hadoop、Hive、Kafka、RDBMS等数据源抽取数据,并构建Cube,数据以关系表的形式输入,且必须符合星形模型或雪花模型,用户可以选择使用MapReduce或Spark进行构建,构建后的Cube保存在存储引擎中,默认的存储引擎为HBase。
由于连接、聚合等复杂计算在离线的预计算过程中就已经完成,查询时刻所需的计算量相应大幅减少,响应速度则大幅提升,在超大数据集上也能实现亚秒级响应。
从性能来说,Kylin这种以时间换空间带来的响应速度提升是突破性的,前面提到的Hive的分钟级的,Spark SQL和Presto是秒级,亚秒级的Kylin对于交互查询体验的提升效果显而易见。
2015年,Kylin成为Apache顶级项目,这也是首个由国内团队完整贡献到Apache的顶级项目。直到现在,Kylin仍然是最具代表性的MOLAP引擎。
Impala
Impala由Cloudera公司主导开发,2012年首次发布,2015年捐献给Apache基金会,2017年成为Apache顶级项目。
从时间来看,Impala与Presto几乎同时出现,面对的历史背景也是Hive性能不够给力,其目标即是成为Hive的高性能替代方案。
Impala的设计思路受谷歌于2010年发布的论文Dremel启发,最开始时Cloudera甚至直接宣称Impala是Dremel开源实现版本。
根据Dremel的设想,可以让计算节点和存储节点放在同一台Server上;进程常驻,做好缓存,确保不会用大量时间做冷启动;树状架构,多层聚合,这样可以让单个节点响应时间和计算量都较小,能够快速拿到返回结果……这些思路深刻影响了Impala的架构。
Impala是构建在hadoop上的查询工具,作为SQL on Hadoop计算引擎,从客户端使用来看 Impala 与 Hive 有很多的共同之处,如数据表元数据、 ODBC/JDBC 驱动、 SQL 语法、灵活的文件格式、存储资源池等。
但与Hive不同的是,Impala把整个查询分成一执行计划树,而不是一连串的 MapReduce 任务,在分发执行计划后, Impala 使用拉式获取数据的方式获取结果,把结果数据组成按执行树流式传递汇集,减少了把中间结果落盘的开销。
另外,Impala 使用服务的方式避免每次执行查询都需要启动的开销,即相比 Hive 没了 MapReduce 启动时间。
Impala可以分析存储在HDFS和HBase中的数据,并直接重用Hive的元数据服务。与传统MPP系统不太相同的地方在于,Impala实现了计算引擎与存储引擎的分离,数据的计算与文件存储系统并不是强耦合关系。
从性能上来说,Impala与Presto是同一量级,但并不具备Presto那种多数据源联邦查询特性,在国内的应用也远没有Presto广泛。
Druid
Druid由美国广告技术公司MetaMarkets 2011 年创建,后来被LinkedIn收购,并于2012年开源。
前面提到的几款引擎最初针对的都是离线场景,Presto、Impala这样的查询引擎搭配后来出现的一些如Iceberg之类的湖组件,倒是可以搭建分钟级更新的实时分析系统,但在Druid问世的时候,实时分析还并不成熟。
而Druid的一个重要优势,即是能够对实时数据进行快速处理和分析,其数据处理层包括了实时数据流和离线数据流两种方式,其中,实时数据流采用的是流处理引擎,如Storm和Spark,可以实时地采集和处理数据,并将数据置入Druid数据存储层。
Druid一般被归为MOLAP类别,在数据入库时就提前进行了聚合,也就是所谓的预聚合。MOLAP引擎在性能上是有天然优势的,Druid在大数据量下的交互查询响应速度跟Kylin是同一量级,都是亚秒级的。
Clickhouse
ClickHouse由俄罗斯的Yandex于2016年开源,应该是国内前两年人气最高的OLAP组件,没有之一。
ClickHouse最大的优势就是快,在其问世的时候,性能基本没有对手,部分场景下响应速度是Presto的10倍以上。至于其为什么这么快,其中一个重要因素是近几年几乎成为OLAP标配的向量化执行引擎。
相比于传统火山模型中的逐行处理模式,向量化执行引擎采用批量处理模式,可以大幅减少函数调用开销,降低指令、数据的 Cache Miss,提升 CPU 利用效率,并且ClickHouse 可利用 SIMD 指令进一步加速执行效率,这一技术的应用从当时来看具有明显的领先性。
除了向量化执行,ClickHouse还拥有其它很多能够有效提升性能的设计,比如,支持丰富的索引,从而在查询时尽可能的裁剪不必要的记录读取;支持一定的MOLAP能力,通过预计算提前生成聚合后的结果数据,降低查询读取的数据量。
总体上,ClickHouse将OLAP的性能拉到了一个新的高度。而得益于其出色的性能表现,它也大量被用在实时分析场景下。
与此同时,ClickHouse也有一些显而易见的缺陷,其中最难忍的是面对join查询时的无力,这也导致其覆盖的需求场景受到了很大局限。
Greenplum
Greenplum一款基于postgresql的MPP架构分布式数据库,于2008年正式发布,2010年,Greenplum的创始团队被存储领域巨头EMC公司收购,2014年,Greenplum数据库从EMC公司独立出来,成为Pivotal公司的产品,2015年10月,Pivotal公司正式将Greenplum开源。
虽然Greenplum作为产品出现是在2008年,但作为公司的Greenplum则是在2003年成立的,彼时,hadoop还未问世,企业面对数据暴增时的通常做法是往主机里加cpu、内存、硬盘,这就是所谓的Scale-up(纵向扩展)模式,而在海量数据面前,这种模式越来越难以为继。
从现在的视角来看,采用Scale-out(横向扩展)模式加机器显然更加靠谱,但当时还缺少基于集群的OLAP工具,而Greenplum正是在这一背景下开始开发的。
借助于分布式计算思想,Greenplum实现了基于数据库的分布式数据存储和并行计算,其内部有一个名为Interconnect的核心组件,在Interconnect的指挥协调下,数十个甚至数千个Sub Postgresql数据库实例可以同时开展并行计算,这些Postgresql之间采用share-nothing无共享架构,从而更将这种并行计算能力发挥到极致。
由于采用Postgresl作为底层引擎,Greenplum良好的兼容了Postgresql的功能,Postgresql中的功能模块和接口基本上99%都可以在Greenplum上使用。
StarRocks
StarRocks开源于2021年,是OLAP引擎中名副其实的后来者,但也是时下国内最热门的开源OLAP组件之一,微信、腾讯游戏、小红书、滴滴、B站、米哈游等互联网大厂已纷纷将其引入到生产环境中,甚至担任起主力引擎的重任。
在StarRocks问世时,国内的离线、实时数仓方案其实都已经比较成熟,前面提到的几款引擎基本上主导了大厂数仓建设,由于各引擎的优势各有侧重,企业往往会采用多种引擎来适应不同的需求。
StarRocks最初主要的优势是性能,当时在单表查询方面与性能标杆ClickHouse不相上下,而join优化特性使其在多表关联查询场景下的性能表现要远远优于ClickHouse,替换ClickHouse自然也就成了StarRocks的第一个目标。
而StarRocks的野心不止于此,后来又进一步发展了联邦查询功能,成为Presto的性能升级替代方案。与此同时,StarRocks优良的预计算特性让其成为Druid的一种替代选择。