系列 | 漫谈数仓第五篇NO.5 『OLAP』

系列 | 漫谈数仓第五篇NO.5 『OLAP』

一 概念

1.1 什么是OLAP?

OLAP(OnLine Analytical Processing),即联机分析处理。OLAP对业务数据执行多维分析,并提供复杂计算,趋势分析和复杂数据建模的能力。它主要用于支持企业决策管理分析,是许多商务智能(BI)应用程序背后的技术。OLAP使最终用户可以对多个维度的数据进行即席分析,从而获取他们所需知识,以便更好地制定决策。OLAP技术已被定义为实现“快速访问共享的多维信息”的能力。

1.2 为什么要多维分析?

业务其实是一个多维活动。企业通过考虑许多变量来跟踪其业务活动,在电子表格上跟踪这些变量时,将它们设置在轴(x和y)上。例如,可以在一年的时间内按月跟踪销售额,其中可以在y轴上显示销售指标,而在x轴上可以显示月份。而要分析业务的健康状况并计划未来的活动,必须连续跟踪许多变量组或参数。例如,一个业务至少要考虑以下方面:客户,地点,期间,销售人员和产品。这些维度构成了公司计划,分析和报告活动的基础。它们共同代表了“整个”业务状况,为所有业务计划、分析和报告活动奠定了基础。

1.3 OLAP的起源

OLAP这个名词最早是在1993年,由被称为“关系数据库之父”的Edgar F. Codd在他的白皮书《Providing OLAP to User-Analysts: An IT Mandate》中首次提出的。在这个白皮书中,他为OLAP产品建立了12条评估规则:

  1. Multidimensional Conceptual View(多维概念视图):在用户分析师看来,企业天然是多维的。例如,可以按地区,产品,时间段或方案(例如实际,预算或预测)查看利润。多维数据模型使用户能够更直接,更直观地处理数据,包括“分片和分块”。
  2. Transparency(透明性准则):OLAP应该是开放系统体系结构的一部分,该体系结构可以嵌入到用户期望的任何位置,而不会影响宿主工具的功能。不应把OLAP工具的数据源暴露给用户,数据源可能是同构的或异构的。
  3. Accessibility(存取能力推测):OLAP工具应该能够应用自己的逻辑结构来访问异构数据源,并执行向用户呈现连贯视图所需的任何转换。工具(而不是用户)应关注物理数据的来源。
  4. Consistent Reporting Performance(稳定的报表性能):随着维度数量的增加,OLAP工具的性能不会受到显著影响。
  5. Client-Server Architecture(客户/服务器架构):OLAP工具的服务器组件应该足够智能,各种客户端可以轻松地连接它。服务器应该能够在不同的数据库之间映射和合并数据。
  6. Generic Dimensionalityc(维的等同性准则):每个数据维度的结构和操作能力都应相同。
  7. Dynamic Sparse Matrix Handling(动态的稀疏矩阵处理准则):OLAP服务器的物理结构应具有最佳的稀疏矩阵处理。
  8. Multi-User Support(多用户支持能力准则):OLAP工具必须提供并发检索和更新访问,完整性和安全性。
  9. Unrestricted Cross-dimensional Operations(非受限的跨维操作):计算设施必须允许跨任意数量的数据维度进行计算和数据处理,并且不得限制数据单元之间的任何关系。
  10. Intuitive Data Manipulation(直观的数据操作):合并路径中固有的数据操作,例如向下钻取或缩小,应通过对分析模型单元的直接操作来完成,而不需要使用菜单或跨用户界面多次行程。
  11. Flexible Reporting(灵活的报告生成):报告工具应以用户想要查看的任何方式显示信息。
  12. Unlimited Dimensions and Aggregation Levels(不受限的维度和聚合层次)。

1.4 OLAP的发展历史

虽然OLAP的概念是在1993年才提出来的,但是支持OLAP相关产品的发展历史,最早可追溯到1975年:

  1. 第一款OLAP产品Express于1975年问世,随着被Oracle收购后繁荣发展了30余年,最后由继任者Oracle 9i替代。
  2. 1979年,第一个电子表格应用程序VisiCalc投放市场。VisiCalc具有当今大多数电子表格应用程序中标准的基本行和列结构。
  3. 1982年,Comshare开发了一种新的决策支持系统软件(System W),这是第一个金融领域的OLAP工具,也是第一个在其多维建模中应用hypercube方法的工具。
  4. 1983年,IBM推出了Lotus 1-2-3。它的结构类似于Visicalc,并迅速取代了Visicalc。Lotus 1-2-3成为Windows之前的主流电子表格应用程序。
  5. 1984年,第一款ROLAP产品Metaphor发布。该多维产品建立了新概念,例如客户/服务器计算,关系数据的多维处理,工作组处理,面向对象的开发等。
  6. 1985年,Excel 1.0诞生。微软在Excel中集成了数据透视表功能可能是Excel产品最重要的增强功能之一,因为数据透视表已成为多维分析中最流行和使用最广泛的工具。

1989年,SQL语言标准诞生,它可以从关系数据库中提取和处理业务数据。这可能是个转折点。在1980‘s年代,电子表格在OLAP应用中占绝对主导地位;而1990’s年代以后,越来越多的基于数据库的OLAP应用开始出现:

  1. 1992年:Hyperion Solution发布Essbase(扩展电子表格数据库),在1997年成为市场上主要的OLAP服务器产品。
  2. 1997年:PARIS Technologies推出PowerOLAP:集成电子表格和事务数据库,以便在电子表格应用程序(例如Excel)中即时更新数据。
  3. 1999年:Microsoft OLAP服务发布,并于2000年成为Microsoft Analysis Services
  4. 2012年:PARIS Technologies发布了OLATION,它将关系和多维数据库技术(在SQL Server,SAP HANA,Oracle等中)融合在一起,确保对实际数据和计划数据进行“真正的在线”数据更新。

1.5 OLAP的核心概念和基本操作

1.5.1 核心概念

维度(Dimension):维度是描述与业务主题相关的一组属性,单个属性或属性集合可以构成一个维。如时间、地理位置、年龄和性别等都是维度。

维的层次(Level of Dimension):一个维往往可以具有多个层次,例如时间维度分为年、季度、月和日等层次,地区维可以是国家、地区、省、市等层次。这里的层次表示数据细化程度,对应概念分层。后面介绍的上卷操作就是由低层概念映射到高层概念。概念分层除了可以根据概念的全序和偏序关系确定外,还可以通过对数据进行离散化和分组实现。

维的成员(Member of Dimension):若维是多层次的,则不同的层次的取值构成一个维成员。部分维层次同样可以构成维成员,例如“某年某季度”、“某季某月”等都可以是时间维的成员。

度量(Measure):表示事实在某一个维成员上的取值。例如开发部门汉族男性有39人,就表示在部门、民族、性别三个维度上,企业人数的事实度量。

1.5.2 基本操作

OLAP的操作是以查询——也就是数据库的SELECT操作为主,但是查询可以很复杂,比如基于关系数据库的查询可以多表关联,可以使用COUNT、SUM、AVG等聚合函数。OLAP正是基于多维模型定义了一些常见的面向分析的操作类型是这些操作显得更加直观。

OLAP的多维分析操作包括:钻取(Drill-down上卷(Roll-up切片(Slice切块(Dice以及旋转(Pivot)**,下面还是以数据立方体为例来逐一解释下:

www.zeeklog.com  - 系列 | 漫谈数仓第五篇NO.5 『OLAP』

钻取(Drill-down):在维的不同层次间的变化,从上层降到下一层,或者说是将汇总数据拆分到更细节的数据,比如通过对2010年第二季度的总销售数据进行钻取来查看2010年第二季度4、5、6每个月的消费数据,如上图;当然也可以钻取浙江省来查看杭州市、宁波市、温州市……这些城市的销售数据。

上卷(Roll-up):钻取的逆操作,即从细粒度数据向高层的聚合,如将江苏省、上海市和浙江省的销售数据进行汇总来查看江浙沪地区的销售数据,如上图。

切片(Slice):选择维中特定的值进行分析,比如只选择电子产品的销售数据,或者2010年第二季度的数据。

切块(Dice):选择维中特定区间的数据或者某批特定值进行分析,比如选择2010年第一季度到2010年第二季度的销售数据,或者是电子产品和日用品的销售数据。

旋转(Pivot):即维的位置的互换,就像是二维表的行列转换,如图中通过旋转实现产品维和地域维的互换。

1.6 OLAP的分类

按数据存储方式分类,可分为MOLAP、ROLAP、HOLAP。

1.6.1 Multidimensional OLAP (MOLAP)

MOLAP是OLAP的经典形式。MOLAP将数据存储在优化的多维数组中,而不是关系数据库中。维的属性值被映射成多维数组的下标值或下标的范围,而度量数据作为多维数组的值存储在数组的单元中。由于MOLAP采用了新的存储结构,从物理层实现,因此又称为物理OLAP(PhysicalOLAP);而 ROLAP主要通过一些软件工具或中间软件实现,物理层仍采用关系数据库的存储结构,因此称为虚拟OLAP(VirtualOLAP)。

一些MOLAP工具要求对数据进行预计算和存储,这样的MOLAP工具通常利用被称为“数据立方体”的预先计算的数据集。数据立方体包含给定范围的问题的所有可能答案。因此,它们对查询的响应非常快。另一方面,根据预计算的程度,更新可能需要很长时间。预计算也可能导致所谓的数据爆炸。

1.6.2 Relational OLAP(ROLAP)

ROLAP将分析用的多维数据存储在关系数据库中。这种方式依赖SQL语言实现传统OLAP的切片和切块功能,本质上,切片和切块等动作都等同于在SQL语句中添加“ WHERE”子句。ROLAP工具不使用预先计算的多维数据集,而是对标准关系数据库及其表进行查询,以获取回答问题所需的数据。ROLAP工具具有询问任何问题的能力,因为该方法(SQL)不仅限于多维数据集的内容。

尽管ROLAP使用关系数据库作为底层存储,但这些数据库一般要针对ROLAP进行相应优化,比如并行存储、并行查询、并行数据管理、基于成本的查询优化、位图索引、SQL的OLAP扩展(cube,rollup)等等。专为OLTP设计的数据库不能像ROLAP数据库一样正常工作。

1.6.3 Hybrid OLAP(HOLAP)

由于MOLAP和ROLAP有着各自的优点和缺点,且它们的结构迥然不同,这给分析人员设计OLAP结构提出了难题。为此一个新的OLAP 结构——混合型OLAP(HOLAP)被提出,这种工具通过允许同时使用多维数据库(MDDB)和关系数据库(RDBMS)作为数据存储来弥合这两种产品的技术差距。它允许模型设计者决定将哪些数据存储在MDDB中,哪些存储在RDBMS中, 例如,将大量详单数据存储在关系表中,而预先计算的聚合数据存储在多维数据集中。目前整个行业对于“混合OLAP”的还没有达成明确的共识。

1.6.4 MOLAP与ROLAP对比分析
www.zeeklog.com  - 系列 | 漫谈数仓第五篇NO.5 『OLAP』

1.7 OLAP与其他概念的关系

1.7.1 OLAP vs OLTP

两者设计的目标是完全不同的:

  1. OLTP(On-Line Transaction Processing),联机事务处理,一般用于业务系统。OLTP对事务性处理的要求非常高,一般都是高可用的在线系统,主要基于传统的关系型数据库。其上的应用,一般以小的事务以及小的查询为主。评估其系统的时候,一般看其每秒执行的Transaction以及SQL的数量。在这样的系统中,单个数据库每秒处理的Transaction(增、删、改)往往达到几百上千个,Select查询语句的执行量每秒几千甚至几万个。典型的OLTP系统有电子商务系统、银行交易系统、证券交易系统等。
  2. OLAP,一般用于分析系统。其上的应用,一般以大数据量的查询为主,修改和删除的操作较少。在这样的系统中,SQL语句的执行量不是考核指标,因为一条语句的执行时间可能会很长,读取的数据也非常多。所以,评估其系统的时候,往往是看系统的吞吐量、复杂查询响应时间、数据装载性能等。

二者详细对比如下:

www.zeeklog.com  - 系列 | 漫谈数仓第五篇NO.5 『OLAP』
www.zeeklog.com  - 系列 | 漫谈数仓第五篇NO.5 『OLAP』
1.7.2 OLAP vs 数据仓库/数据集市

数据仓库的建模方式有多种:

  1. ER模型(实体-关系模型)
  2. Data Vault模型
  3. Anchor模型
  4. 维度模型

前面三种模型主要致力将各个业务系统中的数据整合到统一的数据仓库中,并进行一致性处理,提供满足第三范式或更高范式的数据模型和原子数据。这种数据仓库被称为CIF(Corporate Information Factory,企业信息工厂)架构下的企业数据仓库。这种数据仓库架构是数据仓库之父Inmon所推崇的。但由于使用了规范化模型,这使得对这些原子数据进行查询变得很困难,这种架构并不能很好地直接用于支撑分析决策。为了更好的支持分析,在这种架构下,通常需要在数据仓库的基础上,按主题建立一些数据子集,也就是数据集市。这些数据集市通常采用维度模型,OLAP工具就可以基于数据集市而工作。数据集市通常就是基于OLAP系统而构建。

www.zeeklog.com  - 系列 | 漫谈数仓第五篇NO.5 『OLAP』

第四种模型(维度模型)是另一位数据仓库领域的大师Kimball提出的,是目前数据仓库领域最流行的建模方式。维度模型可以很好地支撑分析决策需求,同时还有较好的大规模复杂查询的响应性能。维度模型可以直接使用OLAP工具与其对接。Kimball所推崇的数据仓库架构如下,基于这种架构建立的数据仓库,可以直接提供OLAP能力。这样建立的数据仓库本身也就成为了一个OLAP系统。

www.zeeklog.com  - 系列 | 漫谈数仓第五篇NO.5 『OLAP』
1.7.3 OLAP vs BI工具

BI是Business Intelligence的英文缩写,中文解释为商务智能,是利用数据提高决策质量的技术集合,是从大量的数据中钻取信息与知识的过程。OLAP和BI常常在一起出现,OLAP是BI工具的一种底层技术。BI工具通常可以对接OLAP系统,但不限于此,也可以直接与其他数据库、存储系统对接。

1.7.4 OLAP vs 即席查询

Ad hoc是一个拉丁文常用短语,意思是“特设的、特定目的的(地)、临时的、专案的”。即席查询(Ad Hoc Queries)是指用户根据自己的需求动态创建的查询,与预定义查询相反。

即席查询对数据模型没有要求,只要能提供动态查询的能力即可;而OLAP系统,一般要求数据模型是多维数据模型。对于ROLAP系统,通常都能提供即席查询能力,二者之间差别很小,所以经常混用。

二 开源组件

开源大数据OLAP组件,可以分为MOLAP和ROLAP两类。ROLAP中又可细分为MPP数据库和SQL引擎两类。对于SQL引擎又可以再细分为基于MPP架构的SQL引擎和基于通用计算框架的SQL引擎:

www.zeeklog.com  - 系列 | 漫谈数仓第五篇NO.5 『OLAP』
  1. MOLAP一般对数据存储有优化,并且进行部分预计算,因此查询性能最高。但通常对查询灵活性有限制。
  2. MPP数据库是个完整的数据库,通常数据需要导入其中才能完成OLAP功能。MPP数据库在数据入库时对数据分布可以做优化,虽然入库效率有一定下降,但是对后期查询性能的提高有很大帮助。MPP数据库可以提供灵活的即席查询能力,但一般对查询数据量有一定限制,无法支撑特别大的数据量的查询。
  3. SQL引擎只提供SQL执行的能力,本身一般不负责数据存储,通常可以对接多种数据储存,如HDFS、HBase、MySQL等。有的还支持联邦查询能力,可以对多个异构数据源进行联合分析。SQL引擎中,基于MPP架构的SQL引擎,一般对在线查询场景有特殊优化,所以端到端查询性能一般要高于基于通用计算框架的SQL引擎;但是在容错性和数据量方面又会逊于基于通用计算框架的SQL引擎。

总之,可以说没有一个OLAP系统能同时在处理规模,灵活性和性能这三个方面做到完美,用户需要基于自己的需求进行取舍和选型。

2.1 开源MOLAP系统分析

2.1.1 Kylin

Apache Kylin 是一个开源的分布式分析引擎,提供 Hadoop/Spark 之上的 SQL 查询接口及多维分析(OLAP)能力以支持超大规模数据,它能在亚秒内查询巨大的 Hive 表。Kylin的核心思想是预计算,理论基础是:以空间换时间。即将多维分析可能用到的度量进行预计算,将计算好的结果保存成Cube并存储到HBase中,供查询时直接访问。把高复杂度的聚合运算,多表连接等操作转换成对预计算结果的查询。

www.zeeklog.com  - 系列 | 漫谈数仓第五篇NO.5 『OLAP』

Kylin的核心模块:

  1. REST Server:提供 Restful 接口,例如创建、构建、刷新、合并等 Cube 相关操作,Kylin 的 Projects、Tables 等元数据管理,用户访问权限控制,SQL 的查询等;
  2. Query Engine:使用开源的 Apache Calcite 框架来实现 SQL 解析,可以理解为 SQL 引擎层;
  3. Routing:负责将解析 SQL 生成的执行计划转换成 Cube 缓存的查询,这部分查询是可以在秒级甚至毫秒级完成;
  4. Metadata:Kylin 中有大量的元数据信息,包括 Cube 的定义、星型模型的定义、Job 和执行 Job 的输出信息、模型的维度信息等等,Kylin 的元数据和 Cube 都存储在 HBase 中,存储的格式是 json 字符串;
  5. Cube Build Engine:所有模块的基础,它主要负责 Kylin 预计算中创建 Cube,创建的过程是首先通过 Hive 读取原始数据,然后通过一些 MapReduce 或 Spark 计算生成 Htable,最后将数据 load 到 HBase 表中。

整个系统分为两部分:

  1. 离线构建:
  • 数据源在左侧,目前主要是 Hadoop Hive,保存着待分析的用户数据;
  • 根据元数据的定义,下方构建引擎从数据源抽取数据,并构建 Cube;
  • 数据以关系表的形式输入,支持星形模型和雪花模型;
  • 2.5 开始 Spark 是主要的构建技术(以前是MapReduce);
  • 构建后的 Cube 保存在右侧的存储引擎中,一般选用 HBase 作为存储。
  • 在线查询
  • 用户可以从上方查询系统(Rest API、JDBC/ODBC)发送 SQL 进行查询分析;
  • 无论从哪个接口进入,SQL 最终都会来到 Rest 服务层,再转交给查询引擎进行处理;
  • 查询引擎解析 SQL,生成基于关系表的逻辑执行计划;
  • 然后将其转译为基于 Cube 的物理执行计划;
  • 最后查询预计算生成的 Cube 并产生结果。
  • 优点
  1. 亚秒级查询响应;
  2. 支持百亿、千亿甚至万亿级别交互式分析;
  3. 无缝与 BI 工具集成;
  4. 支持增量刷新;
  • 缺点
  1. 由于 Kylin 是一个分析引擎,只读,不支持 insert, update, delete 等 SQL 操作,用户修改数据的话需要重新批量导入(构建);
  2. 需要预先建立模型后加载数据到 Cube 后才可进行查询
  3. 使用 Kylin 的建模人员需要了解一定的数据仓库知识。
2.1.2 Druid

Apache Druid是高性能的实时分析数据库,主要提供对大量的基于时序的数据进行OLAP查询能力。支持毫秒级的快速的交互式查询。

www.zeeklog.com  - 系列 | 漫谈数仓第五篇NO.5 『OLAP』

Druid有几种进程类型,简要描述如下:

  1. Coordinators协调器进程:负责监控数据服务器上的Historicals进程,将Segments分配给特定的服务器,并负责确保Segments在多个Historicals之间保持平衡。
  2. Overlords进程:负责监控数据服务器上的MiddleManager进程,并控制数据获取任务的分配。
  3. Broker代理进程:处理来自外部客户端的查询,将查询转发给数据服务器去执行,并合并来自多个数据服务器的结果,返回给最终用户。
  4. Routers进程:是个可选进程,提供统一的API Gateway,可以将请求路由到Brokers、Overlords和Coordinators。
  5. Historicals进程:负责处理“历史数据”的查询。它会从Deep Storage下载查询需要的Segments以加速查询。它不负责写入。
  6. MiddleManager进程:负责处理获取到新数据,从外部数据源读取数据并转换成Segments进行存储。

Druid进程可以按照任何方式进行部署,但是为了易于部署,一般建议将它们组织为三种服务器类型:

  1. 主服务器:运行Coordinatos和Overlords进程,负责管理数据获取和数据可用性。
  2. 查询服务器:运行Brokers和可选的Routers进程,处理来自外部客户端的查询。
  3. 数据服务器:运行Historicals和MiddleManagers进程,负责执行数据获取任务并存储所有可查询的数据。

Druid之所以查询如此之快,与它针对多维数据优化的组织和存储方式有很大关系。它将数据索引存储在Segments文件中,Segment文件按列来存储,并通过时间分区来进行横向分割。Druid将数据列分为了三种不同的类型:

www.zeeklog.com  - 系列 | 漫谈数仓第五篇NO.5 『OLAP』
  1. 对于时间列和指标列处理比较简单,直接用lz4压缩存储。一旦查询知道去找哪几行,只需要将它们解压,然后用相应的操作符来操作它们就可以了。

对于维度列就没那么简单了,因为它们需要支持过滤和聚合操作,因此每个维度需要下面三个数据结构:

(1) 一个map,Key是维度的值,值是一个整型的id

(2) 一个存储列的值得列表,用(1)中的map编码的list

(3) 对于列中的每个值对应一个bitmap,这个bitmap用来指示哪些行包含这个个值。

1: 字典

{    "Justin BIeber": 0,    "Ke$ha":         1}

2. 值的列表

[0, 0, 1, 1]

3. bitMap

value="Justin Bieber": [1, 1, 0, 0]value="Ke$ha":         [0, 0, 1, 1]

为什么要使用这三个数据结构?map将字符串值映射为整数id,以便可以紧凑地表示(2)和(3)中的值。(3)中的bitmap(也被称为倒排索引)允许快速过滤操作(特别地,bitmap便于快速进行AND和OR运算),这样,对于过滤再聚合的场景,无需访问(2)中的维度值列表。最后,(2)中的值可以被用来支持group by和TopN查询。

  • 优点:
  1. 为分析而设计:为OLAP工作流的探索性分析而构建。它支持各种filter、aggregator和查询类型。
  2. 交互式查询:低延迟数据摄取架构允许事件在它们创建后毫秒内查询。
  3. 高可用:你的数据在系统更新时依然可用、可查询。规模的扩大和缩小不会造成数据丢失。
  4. 可伸缩:每天处理数十亿事件和TB级数据。
  • 缺点:
  1. 不支持更新操作,数据不可更改
  2. 不支持事实表之间的关联

2.2 开源MPP数据库分析

2.2.1 Greenplum

GreenPlum是基于PostgreSQL的开源MPP数据库,具有良好的线性扩展能力,具有高效的并行运算和并行存储特性。

www.zeeklog.com  - 系列 | 漫谈数仓第五篇NO.5 『OLAP』

Greenplum的系统架构实际上是多台PostgreSQL数据库服务器组成的矩阵,采用无共享(no shareing)的MPP架构:

  1. Master节点:作为数据库的入口,负责客服端连接;对客服端的请求生成查询计划,分发给某个或者所有的Segment节点。
  2. Standby节点 : 作为master节点的备库,提供高可用性。
  3. Interconnect:是GreenPlum的网络层;负责每个节点之间的通信。
  4. Segment节点:为数据节点;接收master分发下来的查询计划;执行返回结果给master节点。
  5. Mirror Segment节点:作为Segment节点的备库,提供高可用性;通常跟对应的segment节点不在同一台机器上。
  • 优点
  1. 支持多态数据存储,允许用户根据应用定义数据分布方式,可提高查询性能。
  2. 具有高效的SQL优化器,针对OLAP查询进行优化。
  • 缺点:
  1. 存在“木桶效应”,单机故障会导致性能严重下降,因此集群规模不能太大。
  2. 并发性能不高,通常无法支持超过30个并发。
2.2.2 ClickHouse

ClickHouse是Yandex(号称俄罗斯的‘百度’)开源的MPP架构的列式存储数据库。

目前ClickHouse公开的资料相对匮乏,比如在架构设计层面就很难找到完整的资料,甚至连一张整体的架构图都没有。

  • ClickHouse为什么性能这么好?
  1. 着眼硬件。基于将硬件功效最大化的目的,ClickHouse会在内存中进行GROUP BY;与此同时,他们非常在意CPU L3级别的缓存,因为一次L3的缓存失效会带来70~100ns的延迟,意味着在单核CPU上,它会浪费4000万次/秒的运算。正因为注意了这些细节,所以ClickHouse在基准查询中能做到1.75亿次/秒的数据扫描性能。
  2. 注重算法。例如,在字符串搜索方面,针对不同的场景,ClickHouse选择了多种算法:对于常量,使用Volnitsky算法;对于非常量,使用CPU的向量化执行SIMD,暴力优化;正则匹配使用re2和hyperscan算法。除了字符串之外,其余的场景也与它类似,ClickHouse会使用最合适、最快的算法。如果世面上出现了号称性能强大的新算法,ClickHouse团队会立即将其纳入并进行验证。
  3. 特定场景,特殊优化。针对同一个场景的不同状况,选择使用不同的实现方式,尽可能将性能最大化。对于数据结构比较清晰的场景,会通过代码生成技术实现循环展开,以减少循环次数。
  4. 向量化执行。SIMD被广泛地应用于文本转换、数据过滤、数据解压和JSON转换等场景。相较于单纯地使用CPU,利用寄存器暴力优化也算是一种降维打击了。
  • 优点
  1. 速度快
  • 缺点:
  1. 不支持事务,不支持真正的删除/更新;
  2. 不支持高并发,Clickhouse快是因为采用了并行处理机制,即使一个查询,也会用服务器一半的CPU去执行。
  3. join性能不高
  4. 开源社区主要是俄语为主.

2.3 基于MPP架构的SQL引擎分析

2.3.1 Presto

Presto是Facebook推出分布式SQL交互式查询引擎,完全基于内存的并行计算,支持任意数据源,数据规模GB~PB。

www.zeeklog.com  - 系列 | 漫谈数仓第五篇NO.5 『OLAP』

Presto采用典型的Master-Slave架构:

  1. coordinator:是presto集群的master节点。负责解析SQL语句,生成执行计划,分发执行任务给Worker节点执行。
  2. worker:是执行任务的节点。负责实际查询任务的计算和读写。
  3. discovery service:是将coordinator和worker结合在一起服务。worker节点启动后向discovery service服务注册,coordinator通过discovery service获取注册的worker节点。

connector:presto以插件形式对数据存储层进行了抽象,即connector。可通过connector连接多种数据源,提取数据。

discovery service  将coordinator和worker结合在一起服务;worker节点启动后向discovery service服务注册  coordinator通过discovery service获取注册的worker节点

既然Presto是一个交互式的查询引擎,我们最关心的就是Presto实现低延时查询的原理,我认为主要是下面几个关键点:

  1. 完全基于内存的并行计算
  2. 流水线式计算作业
  3. 本地化计算
  4. 动态编译执行计划
  5. 小心使用内存和数据结构
  6. 类BlinkDB的近似查询
  7. GC控制

与Hive的比较:

www.zeeklog.com  - 系列 | 漫谈数仓第五篇NO.5 『OLAP』

上图显示了MapReduce与Presto的执行过程的不同点,MR每个操作要么需要写磁盘,要么需要等待前一个stage全部完成才开始执行,而Presto将SQL转换为多个stage,每个stage又由多个tasks执行,每个tasks又将分为多个split。所有的task是并行的方式进行允许,stage之间数据是以pipeline形式流式的执行,数据之间的传输也是通过网络以Memory-to-Memory的形式进行,没有磁盘io操作。这也是Presto性能比Hive快很多倍的决定性原因。

  • 与Spark的比较:
  1. 目标:Presto强调查询,但Spark重点强调计算。
  2. 架构:Presto的体系结构与MPP SQL引擎非常相似。这意味着仅针对SQL查询执行进行了高度优化,而Spark是一个通用执行框架,能够运行多个不同的工作负载,如ETL,机器学习等。
  3. 任务启动:Presto的查询没有太多开销。Presto协调器始终处于启动状态并等待查询。而Spark驱动程序启动需要时间与集群管理器协商资源,复制jar,才开始处理。
  4. 任务提交:Spark提交任务并在每个阶段实时应用资源(与presto相比,这种策略可能导致处理速度稍慢); Presto一次申请所需资源,并且一次提交所有任务。
  5. 数据处理:在spark中,数据需要在进入下一阶段之前完全处理。Presto是流水线式处理模式。只要一个page完成处理,就可以将其发送到下一个task(这种方法大大减少了各种查询的端到端响应时间)。
  6. 内存:两者都是内存存储和计算,当它无法获得足够的内存时,spark会将数据写入磁盘,但presto会导致OOM。
  7. 容错:如果Spark任务失败或数据丢失,它将重新计算。但是presto会导致查询失败。
  • 优点:
  1. 基于内存运算,减少没必要的硬盘IO,所以快。
  2. 都能够处理PB级别的海量数据分析。(虽然能够处理PB级别的海量数据分析,但不是代表Presto把PB级别都放在内存中计算的。而是根据场景,如count,avg等聚合运算,是边读数据边计算,再清内存,再读数据再计算,这种耗的内存并不高。)
  3. 能够连接多个数据源,跨数据源关联查询。
  4. 清晰的架构,是一个能够独立运行的系统,不依赖于任何其他外部系统。部署简单。
  • 缺点:
  1. 不适合多个大表的join操作,因为presto是基于内存的,太多数据内存放不下的。
  2. Presto的一个权衡是不关心中间查询容错。如果其中一个Presto工作节点出现故障(例如,关闭),则大多数情况下正在进行的查询将中止并需要重新启动。
2.3.2 HAWQ

HAWQ是Pivotal公司开源的一个Hadoop原生大规模并行SQL分析引擎,针对的是分析型应用。Apache HAWQ 采用主从(Master-Slave)的改进MPP架构,通过将MPP与批处理系统有效的结合,克服了MPP的一些关键的限制问题,如短板效应、并发限制、扩展性等。其整体架构与Pivotal另一开源MPP数据库Greenplum比较相似:

www.zeeklog.com  - 系列 | 漫谈数仓第五篇NO.5 『OLAP』

HAWQ Master节点内部有以下几个重要组件:

  1. 查询解析器(Parser/Analyzer),负责解析查询,并检查语法及语义。最终生成查询树传递给优化器。
  2. 优化器(Optimizer),负责接受查询树,生成查询计划。针对一个查询,可能有数亿个可能的等价的查询计划,但执行性能差异很大。优化器的做用是找出优化的查询计划。
  3. 资源管理器(Resource Manager),资源管理器经过资源代理向全局资源管理器(好比YARN)动态申请资源。并缓存资源。在不须要的时候返回资源。
  4. HDFS元数据缓存(HDFS Catalog Cache),用于HAWQ确定哪些Segment扫描表的哪些部分。HAWQ是把计算派发到数据所在的地方。因此要匹配计算和数据的局部性。如果每一个查询都访问HDFS NameNode会形成NameNode的瓶颈。因此在HAWQ Master节点上创建了HDFS元数据缓存。
  5. 容错服务(Fault Tolerance Service),负责检测哪些节点可用,哪些节点不可用。不可用的机器会被排除出资源池。
  6. 查询派遣器(Dispatcher),优化器优化完查询之后,查询派遣器派遣计划到各个节点上执行,并协调查询执行的整个过程。查询派遣器是整个并行系统的粘合剂。
  7. 元数据服务(Catalog Service),负责存储HAWQ的各类元数据,包括数据库和表信息,以及访问权限信息等。另外,元数据服务也是实现分布式事务的关键。

其余节点为Slave节点。每一个Slave节点上部署有HDFS DataNode,YARN NodeManager以及一个HAWQ Segment。HAWQ Segment在执行查询的时候会启动多个QE (Query Executor, 查询执行器)。查询执行器运行在资源容器里面。节点间数据交换经过Interconnect(高速互联网络)进行。

  • 优点:
  1. 对SQL标准的完善支持:ANSI SQL标准,OLAP扩展,标准JDBC/ODBC支持。
  2. 支持ACID事务特性:这是很多现有基于Hadoop的SQL引擎做不到的,对保证数据一致性很重要。
  3. 动态数据流引擎:基于UDP的高速互联网络。
  4. 多种UDF(用户自定义函数)语言支持:java, python, c/c++, perl, R等。
  5. 动态扩容:动态按需扩容,按照存储大小或者计算需求,秒级添加节点。
  6. 支持MADlib机器学习。
  • 缺点:
  1. 基于GreenPlum实现,技术实现复杂,包含多个组件。比如对于外部数据源,需要通过PXF单独进行处理;
  2. C++实现,对内存的控制比较复杂,如果出现segmentfault直接导致当前node挂掉。
  3. 安装配置复杂;
2.3.3 Impala

Impala是Cloudera在受到Google的Dremel启发下开发的实时交互SQL大数据查询工具。

www.zeeklog.com  - 系列 | 漫谈数仓第五篇NO.5 『OLAP』

Impala采用MPP架构,与存储引擎解耦:

  1. impalad(实例*N): 接收client、hue、jdbc或者odbc请求。每当将查询提交到特定节点上的impalad时,该节点充当该查询的“协调器节点”,负责将Query分发到其他impalad节点来并行化查询,所有查询结果返回给中心协调节点。
  2. StateStore(实例*1): 负责收集分布在各个Impalad进程的资源信息、各节点健康状况,同步节点信息;
  3. Catalog Service(实例*1): 分发表的元数据信息到各个Impalad中,每个Impala节点在本地缓存所有元数据。

与Hive的比较:

Impala 与Hive都是构建在Hadoop之上的数据查询工具,各有不同的侧重点, Hive适合于长时间的批处理查询分析,而Impala适合于实时交互式SQL查询。

  • Hive: 复杂的批处理查询任务,数据转换任务。
  • Impala:实时数据分析,因为不支持UDF,能处理的问题域有一定的限制。
  • Hive: 依赖于Hadoop的容错能力。
  • Impala: 在查询过程中,没有容错逻辑,如果在执行过程中发生故障,则直接返回错误(这与Impala的设计有关,因为Impala定位于实时查询,一次查询失败, 再查一次就好了,再查一次的成本很低)。
  • Hive: 任务调度依赖于Hadoop的调度策略。
  • Impala: 调度由自己完成,目前只有一种调度器simple-schedule,它会尽量满足数据的局部性,扫描数据的进程尽量靠近数据本身所在的物理机器。调度器目前还比较简单,还没有考虑负载,网络IO状况等因素进行调度。但目前 Impala已经有对执行过程的性能统计分析,应该以后版本会利用这些统计信息进行调度吧。
  • Hive: 在执行过程中如果内存放不下所有数据,则会使用外存,以保证Query能顺序执行完。每一轮MapReduce结束,中间结果也会写入HDFS中,同样由于MapReduce执行架构的特性,shuffle过程也会有写本地磁盘的操作。
  • Impala: 在遇到内存放不下数据时,当前版本1.0.1是直接返回错误,而不会利用外存。这使用得Impala目前处理Query会受到一 定的限制。Impala在多个阶段之间利用网络传输数据,在执行过程不会有写磁盘的操作(insert除外)。
  • Hive: 采用推的方式,每一个计算节点计算完成后将数据主动推给后续节点。
  • Impala: 采用拉的方式,后续节点通过getNext主动向前面节点要数据,以此方式数据可以流式的返回给客户端,且只要有1条数据被处理完,就可以立即展现出来,而不用等到全部处理完成,更符合SQL交互式查询使用。
  • Hive: 依赖于MapReduce执行框架,执行计划分成 map->shuffle->reduce->map->shuffle->reduce…的模型。如果一个Query会 被编译成多轮MapReduce,则会有更多的写中间结果。由于MapReduce执行框架本身的特点,过多的中间过程会增加整个Query的执行时间。
  • Impala: 把执行计划表现为一棵完整的执行计划树,可以更自然地分发执行计划到各个Impalad执行查询,而不用像Hive那样把它组合成管道型的 map->reduce模式,以此保证Impala有更好的并发性和避免不必要的中间sort与shuffle。
  1. 数据存储:使用相同的存储数据池都支持把数据存储于HDFS, HBase。
  2. 元数据:两者使用相同的元数据。
  3. SQL解释处理:比较相似都是通过词法分析生成执行计划。
  4. 执行计划:
  5. 数据流:
  6. 内存使用:
  7. 调度:
  8. 容错:
  9. 适用面:
  • 优点:
  1. 支持SQL查询,快速查询大数据。
  2. 可以对已有数据进行查询,减少数据的加载,转换。
  3. 多种存储格式可以选择(Parquet, Text, Avro, RCFile, SequeenceFile)。
  4. 可以与Hive配合使用。
  • 缺点:
  1. 不支持用户定义函数UDF。
  2. 不支持text域的全文搜索。
  3. 不支持Transforms。
  4. 不支持查询期的容错。
  5. 对内存要求高。
2.3.4 Drill

Drill是MapR开源的一个低延迟的大数据集的分布式SQL查询引擎,是谷歌Dremel的开源实现。它支持对本地文件、HDFS、HBASE等数据进行数据查询,也支持对如JSON等schema-free的数据进行查询。

www.zeeklog.com  - 系列 | 漫谈数仓第五篇NO.5 『OLAP』

从架构上看,与同是源自Dremel的Impala比较类似。Drill的核心是DrillBit,它主要负责接收客户端的请求,处理查询,并将结果返回给客户端。Drill的查询流程包括以下步骤:

  1. Drill客户端发起查询,任意DrilBit都可以接受来自客户端的查询
  2. 收到请求的DrillBit成为驱动节点(Foreman),对查询进行分析优化生成执行计划,之后将执行计划划分成各个片段(Fragment),并确定合适的节点来执行。
  3. 各个节点执行查询片段(Fragment),并将结果返回给驱动节点
  4. 驱动节点将结果返回给客户端
  • 优点:
  1. 能够自动解析数据(json,text,parquet)的结构。
  2. 支持自定义的嵌套数据集,数据灵活,,支持查询复杂的半结构化数据。
  3. 与Hive一体化(Hive表和视图的查询,支持所有的Hive文件格式和HiveUDFS)。
  4. 支持多数据源,包括NoSQL数据库。
  5. 可以方便的与第三方BI工具对接。
  • 缺点:
  1. SQL语法和常规SQL有区别,一般是如“select * from 插件名.表名”的形式。
  2. 安装部署比较复杂。
  3. GC机制还有待提高。

2.4 基于通用计算框架的SQL引擎分析

2.4.1 SparkSQL

Spark SQL与传统 DBMS 的查询优化器 + 执行器的架构较为类似,只不过其执行器是在分布式环境中实现,并采用的 Spark 作为执行引擎:

www.zeeklog.com  - 系列 | 漫谈数仓第五篇NO.5 『OLAP』

Spark SQL 的查询优化是Catalyst,Catalyst 将 SQL 语言翻译成最终的执行计划,并在这个过程中进行查询优化。这里和传统不太一样的地方就在于, SQL 经过查询优化器最终转换为可执行的查询计划是一个查询树,传统 DB 就可以执行这个查询计划了。而 Spark SQL 最后执行还是会在 Spark 内将这棵执行计划树转换为 Spark 的有向无环图DAG 再执行。

www.zeeklog.com  - 系列 | 漫谈数仓第五篇NO.5 『OLAP』
  • 优点:
  1. 将sql查询与spar无缝融合
  2. 兼容HiveQL
  • 缺点:
  1. 查询性能不高
  2. 以thrift server方式提供的SparkSQL服务不支持多种数据源,必须使用DataFrame API。
2.4.2 Hive

Hive是一个构建于Hadoop顶层的数据仓库工具。定义了简单的类似SQL 的查询语言——HiveQL,可以将HiveQL查询转换为MapReduce 的任务在Hadoop集群上执行。

www.zeeklog.com  - 系列 | 漫谈数仓第五篇NO.5 『OLAP』
  • 优点:
  1. 高可靠、高容错:HiveServer采用集群模式。双MetaStor。超时重试机制。
  2. 类SQL:类似SQL语法,内置大量函数。
  3. 可扩展:自定义存储格式,自定义函数。
  4. 多接口:Beeline,JDBC,ODBC,Python,Thrift。
  • 缺点:
  1. 延迟较高:默认MR为执行引擎,MR延迟较高。
  2. 不支持物化视图:Hive支持普通视图,不支持物化视图。Hive不能再视图上更新、插入、删除数据。
  3. 不适用OLTP:暂不支持列级别的数据添加、更新、删除操作。

2.5 各组件性能对比

测试数据来源于:开源OLAP引擎测评报告。通过测试以及相关调研编写了各组件各个方面的综合对比分析表,这里采用5分为满分来比较,如下表:

www.zeeklog.com  - 系列 | 漫谈数仓第五篇NO.5 『OLAP』
  1. SparkSQL是Hadoop中另一个著名的SQL引擎,它以Spark作为底层计算框架,Spark使用RDD作为分布式程序的工作集合,它提供一种分布式共享内存的受限形式。在分布式共享内存系统中,应用可以向全局地址空间的任意位置进行读写作,而RDD是只读的,对其只能进行创建、转化和求值等作。这种内存操作大大提高了计算速度。SparkSql的性能相对其他的组件要差一些,多表单表查询性能都不突出。
  2. Impala官方宣传其计算速度是一大优点,在实际测试中我们也发现它的多表查询性能和presto差不多,但是单表查询方面却不如presto好。而且Impala有很多不支持的地方,例如:不支持update、delete操作,不支持Date数据类型,不支持ORC文件格式等等,所以我们查询时采用parquet格式进行查询,而且Impala在查询时占用的内存很大。
  3. Presto综合性能比起来要比其余组件好一些,无论是查询性能还是支持的数据源和数据格式方面都要突出一些,在单表查询时性能靠前,多表查询方面性能也很突出。由于Presto是完全基于内存的并行计算,所以presto在查询时占用的内存也不少,但是发现要比Impala少一些,比如多表join需要很大的内存,Impala占用的内存比presto要多。
  4. HAWQ 吸收了先进的基于成本的 SQL 查询优化器,自动生成执行计划,可优化使用hadoop 集群资源。HAWQ 采用 Dynamic pipelining 技术解决这一关键问题。Dynamic pipelining 是一种并行数据流框架,利用线性可扩展加速Hadoop查询,数据直接存储在HDFS上,并且其SQL查询优化器已经为基于HDFS的文件系统性能特征进行过细致的优化。但是我们发现HAWQ在多表查询时比Presto、Impala差一些;而且不适合单表的复杂聚合操作,单表测试性能方面要比其余四种组件差很多,hawq环境搭建也遇到了诸多问题。
  5. ClickHouse 作为目前所有开源MPP计算框架中计算速度最快的,它在做多列的表,同时行数很多的表的查询时,性能是很让人兴奋的,但是在做多表的join时,它的性能是不如单宽表查询的。性能测试结果表明ClickHouse在单表查询方面表现出很大的性能优势,但是在多表查询中性能却比较差,不如presto、impala、hawq的效果好。
  6. GreenPlum作为关系型数据库产品,它的特点主要就是查询速度快,数据装载速度快,批量DML处理快。而且性能可以随着硬件的添加,呈线性增加,拥有非常良好的可扩展性。因此,它主要适用于面向分析的应用。比如构建企业级ODS/EDW,或者数据集市等,GREENPLUM都是不错的选择。
www.zeeklog.com  - 系列 | 漫谈数仓第五篇NO.5 『OLAP』