1.2 各种OLAP引擎的主要特点

1.2.1 Hive

Hive是一个分布式SQL-on-Hadoop(在一个基于Hadoop技术构建的数据仓库环境中使用SQL语言进行数据查询和分析)方案,底层依赖MapReduce执行模型执行分布式计算,如图1-4所示。Hive擅长执行长时间运行的离线批处理任务,数据量越大其优势越明显。Hive在数据量大、数据驱动需求强烈的互联网大厂比较流行。但是近几年,随着ClickHouse的逐渐流行,对于一些总数据量不超过百PB级别的互联网数据仓库需求,已经有多家公司从使用Hive改为使用ClickHouse。ClickHouse的优势是单个查询执行速度更快,不依赖Hadoop,架构和运维更简单,维护成本比Hive低很多。

图1-4 Hive架构

1.2.2 SparkSQL、FlinkSQL

在大部分场景下,Hive计算还是太慢了,不仅不能满足那些要求高QPS、低查询延迟的对外在线服务[1]的需求,就连企业内部的产品、运营、数据分析师也会经常抱怨Hive执行即席查询太慢。这些痛点,推动了MPP内存迭代和DAG(有向无环图)执行模型的诞生和发展,诸如SparkSQL、FlinkSQL、Presto这些技术,目前在企业中也非常流行。SparkSQL、FlinkSQL的执行速度更快,编程API(应用程序编程接口)丰富,同时支持流式计算与批处理,并且有流批统一的趋势,使大数据应用更简单。SparkSQL的查询执行流程如图1-5所示。

1.2.3 ClickHouse

ClickHouse是近年来备受关注的开源列式数据库,主要用于数据分析(OLAP)领域。目前国内社区火热,各个大厂纷纷跟进并大规模使用。

图1-5 SparkSQL查询执行流程

❑ 腾讯用ClickHouse做游戏数据分析,并且为之建立了一整套监控运维体系。

❑ 携程从2018年7月份开始接入试用,目前80%的业务都跑在ClickHouse上,每天数据增加10亿条以上的记录,处理近百万次查询请求。

❑ 快手也在使用ClickHouse,存储总量大约10PB,每天新增200TB,90%查询小于3s。

在国外,Yandex公司有数百节点用ClickHouse做用户点击行为分析,Cloudflare、Spotify等头部公司也在使用ClickHouse。

ClickHouse从OLAP场景需求出发,定制开发了一套全新的高效列式存储引擎,并且实现了数据有序存储、主键索引、稀疏索引、数据分布式分区存储、主备复制等丰富功能。以上功能共同为ClickHouse极速的分析性能奠定了基础。

ClickHouse部署架构简单易用,不依赖Hadoop体系(HDFS+YARN)。它比较擅长的是对一个大数据量的单表进行聚合查询。ClickHouse用C++实现,底层实现具备向量化执行(Vectorized Execution)、减枝等优化能力,具备强劲的查询性能。ClickHouse有广泛使用,比较适合用于内部BI(商业智能)报表型应用,可以提供低延迟(毫秒级别)的响应速度,也就是说单个查询非常快。但是ClickHouse也有它的局限性,在OLAP技术选型的时候,应该避免把它作为多表关联查询(JOIN)的引擎,也应该避免把它用在期望支撑高并发数据查询的场景。在OLAP分析场景中,一般认为QPS达到1000就算高并发,而不是像电商、抢红包等业务场景中,达到10万以上才算高并发。毕竟在数据分析场景中,数据海量且计算复杂,QPS能够达到1000已经非常不容易。例如ClickHouse,如果数据量是TB级别,聚合计算稍复杂一点,单集群QPS一般达到100已经很困难了,所以它更适合用于企业内部BI报表应用,而不适合用于数十万的广告主报表或者数百万的淘宝店主相关报表应用。ClickHouse的执行模型决定了它会尽全力来执行一次查询,而不是同时执行很多查询。

陈峰老师的《ClickHouse性能之巅》一书对ClickHouse做了精妙的总结。ClickHouse能够做到极速的查询性能,主要依赖如下几点。

❑ 向量化的执行引擎,包括基于列式数据格式的列式计算与批式处理,极致地利用现代CPU的SIMD(单指令多数据流)能力。

❑ 执行查询时尽量提高执行并行度。当然这是一把双刃剑,也正是因为这个,ClickHouse无法支撑高QPS的查询场景。

❑ 执行查询时高效的IO(输入输出)速度与对IO读取量的优化,通过高效的数据压缩、数据分块、索引机制等手段实现。

存储引擎是ClickHouse非常重要的一个组件。ClickHouse查询速度快的特点是建立在其设计精妙的存储引警之上的。甚至可以极端地认为,没有对存储引擎的精妙设计,就不会有ClickHouse。在ClickHouse之前,绝大多数大数据技术都是将存储引擎和计算引擎独立设计的。例如MapReduce计算引擎+HDFS存储引擎、Spark计算引擎+HDFS存储引擎等。这些大数据技术都在计算引擎上通过各种令人拍案叫绝的创新实现快速突破,直到ClickHouse的出现。ClickHouse通过协同改造存储引擎和计算引擎,实现了两个引擎的精妙配合,最终达到了如今令人惊艳的查询性能,形成了大数据业界独树一帜的“存储为计算服务”的设计理念。ClickHouse存储引擎的核心在于MergeTree表引擎。

1.2.4 Elasticsearch

提到Elasticsearch(简称ES),很多人的印象是:这是一个开源的分布式搜索引擎,底层依托Lucene倒排索引结构,支持文本分词,非常适合作为搜索服务。这些印象都对,并且用ES作为搜索引擎,一个三节点的集群,支撑1000以上的查询QPS也不是什么难事。

我们这里要讲的是ES的另一个功能,即作为聚合场景的OLAP引擎,它与搜索场景区别很大。聚合场景,可以等同于SELECT c1,c2,SUM(c3),COUNT(c4)FROM table WHERE c1 IN('china','usa')AND c2 < 100这样的SQL,也就是做多维度分组聚合。虽然Elasticsearch DSL是一个复杂的JSON而不是SQL,但是两者意思相同,可以互相转换。

用ES作为OLAP引擎,有如下几个优势。

❑ 擅长高QPS(QPS>1000)、低延迟、过滤条件多、查询模式简单(如点查、简单聚合)的查询场景。

❑ 集群自动化管理能力(数据分片自动分配、恢复、再平衡)非常强。与集群、索引管理和查看相关的API非常丰富。

ES的执行引擎是最简单的Scatter-Gather执行模型,相当于MapReduce执行模型的一轮Map操作和Reduce操作。Scatter和Gather之间的节点数据交换也是基于内存的,不会像MapReduce那样每次要先落盘。ES底层依赖Lucene的文件格式,我们可以把Lucene理解为一种行列混存的模式,并且在查询时通过FST(有限状态转换器,是一种高效的数据结构,用于构建倒排索引)、跳表等加快数据查询。这种Scatter-Gather执行模型的问题是,如果最终聚合(Gather/Reduce)的数据量比较大,那么由于ES是单节点执行的,所以执行速度可能会非常慢。整体来讲,ES是通过牺牲灵活性提高了简单OLAP查询的QPS,降低了延迟。

用ES作为OLAP引擎,有如下几个劣势。

❑ 多维度分组排序、分页。

❑ 不支持关联查询(JOIN)。

❑ 做了聚合操作后,由于返回的数据嵌套层次太多,数据量会过于膨胀。

ES也可以归为宽表模型。但其系统设计架构有较大不同,这两个一般称为搜索引擎,通过倒排索引,应用Scatter-Gather执行模型提高查询性能。ES用于搜索类查询时效果较好,但当数据量较大或进行扫描聚合类查询时,查询性能会有明显下降。

ES的物理存储模型如图1-6所示。

图1-6 ES的物理存储模型

1.2.5 Presto

Presto、Impala、Greenplum均基于MPP架构实现,相比ES、Druid、Kylin这样的简单Scatter-Gather执行模型,其支持的SQL计算更加通用,更适合Ad-hoc(即席查询)场景。然而这些通用系统往往比专用系统更难做性能优化,所以不太适合用于对查询QPS(参考值>1000)、延迟(参考值<500ms)要求比较高的在线服务,更适合用于公司内部的查询服务和加速Hive查询的服务。

Presto还有一个优秀的特性:使用了ANSI标准SQL,并且支持超过30个数据源连接器。这里给读者留一个思考题:以Presto为代表的MPP模型与以Hive为代表的MapReduce模型的性能差异比较大的原因是什么?

Presto的技术架构如图1-7所示,在本书中会常提到此架构。

图1-7 Presto技术架构

1.2.6 Impala

Impala是Cloudera公司在受到Google公司的Dremel启发下开发的实时交互SQL大数据查询工具,是CDH(Hadoop发行版的一种)平台首选的PB级大数据实时查询分析引擎。它拥有和Hadoop一样的可扩展性,它提供了类SQL(类HSQL)语法,在多用户场景下也能拥有较高的响应速度和吞吐量。它是用Java和C++实现的,用Java实现查询交互的接口,用C++实现查询引擎部分。Impala能够共享Hive Metastore,甚至可以直接使用Hive的JDBC jar和Beeline等对Impala进行查询,且支持丰富的数据存储格式(Parquet、Avro等)。此外,Impala没有再使用缓慢的Hive+MapReduce批处理方案,而是通过使用与商用并行关系数据库中类似的分布式查询引擎[2]方案,可以直接从HDFS或HBase中用SELECT、JOIN和统计函数查询数据,从而大大降低了延迟。Impala经常搭配存储引擎Kudu一起提供服务,这么做最大的优势是点查询比较快,并且支持数据的更新和删除。

Impala的技术架构如图1-8所示。

图1-8 Impala技术架构

1.2.7 Doris

Doris是根据Google Mesa论文和Impala项目改写的一个大数据分析引擎,在百度、美团、京东的广告分析等业务中有广泛的应用。Doris的主要功能特性如下。

现代化MPP架构:支持大规模数据集,集群灵活可扩展,支持高并发小查询。

强悍的SQL执行引擎、全新的预聚合技术:支持亚秒级OLAP多维分析,支持高效多表关联分析。

基于LSM(日志结构合并)的列式存储引擎、MVCC(多版本并发控制)事务隔离机制:支持数据高效实时导入,支持数据批量、实时更新。

Doris在国内由于有商业化公司的专门支持,在技术上迭代比较快,企业应用案例也比较多,也会有不定期的线上线下的技术分享、技术峰会等活动。

Doris的技术架构如图1-9所示。

图1-9 Doris技术架构

1.2.8 Druid

Druid是一种能对历史数据和实时数据提供亚秒级别查询的数据存储产品。Druid支持低延迟的数据摄取、灵活的数据探索分析、高性能的数据聚合和简便的水平扩展。Druid支持更大的数据规模,具备一定的预聚合能力,通过倒排索引和位图索引进一步优化查询性能,在广告分析、监控报警等时序类应用场景中有广泛使用。

Druid的特点如下。

❑ Druid可实时消费数据,真正做到数据摄入实时、查询结果实时。

❑ Druid支持PB级数据、千亿级事件快速处理,支持每秒数千次查询并发。

❑ Druid的核心是时间序列,把数据按照时间序列分批存储,十分适合用于对按时间进行统计分析的场景。

❑ Druid把数据列分为时间戳、维度列、指标列三类。

❑ Druid不支持多表连接。

❑ Druid中的数据一般是使用其他计算框架(Spark等)预计算好的低层次统计数据。

❑ Druid不适合用于处理透视维度复杂多变的查询场景。

❑ Druid擅长的查询类型比较单一,一些常用的SQL(GROUP BY等)语句在Druid里运行速度一般。

❑ Druid支持低延迟的数据插入、更新,但是比HBase或传统数据库要慢很多。

与其他时序数据库类似,Druid在查询条件命中大量数据的情况下性能可能会有问题,而且排序、聚合等能力普遍不好,灵活性和扩展性不够高,比如缺乏关联查询(JOIN)、子查询等。

Druid的技术架构如图1-10所示。

图1-10 Druid技术架构

1.2.9 总结

本节对各个OLAP引擎所做的介绍和分析并不一定完全合理、准确,只作为一种选型参考。只有真正有OLAP引擎线上经验的人,在特定业务场景、特定数据量下对以上一种或者几种OLAP引擎做过深度优化的专家才有资格给出技术选型的建议。但是因为这些OLAP引擎技术方案太多,不可能有哪个专家全都精通,所以我们鼓励大家多讨论,多提问题,让自己成为某个OLAP引擎方面的专家。

给大家一个中肯的建议:不要轻易相信各种引擎的性能对比数据报告。笔者也时常在网络上看到这样的文章,文章通过列举各种数据对引擎做排名或展示差距。并不是说这些数据不真实,而是说在上下文未交代清楚的前提下这些数据可能会带来误导性结论。例如拿未经调优的A引擎与经过精心调优的B引擎做比较,B引擎胜之不武。也许A引擎改了某个配置即可完胜B引擎。再例如A、B两个引擎在不同场景下各有优势,但是对比报告中只列出B引擎在某个特定场景下的优势数据而对其他方面避而不谈,很容易使读者以为B引擎全方面胜出。总之大家需要结合实际使用需求,在对调研对象有所认知的前提下,亲自完成公平公正的性能对比。