开源SQL-on-Hadoop系统一览

引言

查询分析是大数据要解决的核心问题之一,而SQL作为查询分析中使用最简单、最广泛的的语言之一,必然而然的催生了许多支持在Hadoop上使用SQL的系统,这就是所谓的SQL-on-Hadoop系统,其中大众熟知的Hive就是最早的SQL-on-Hadoop系统。

经过若干年的发展,SQL-on-Hadoop系统已经百花齐放,按照架构划分这些系统大致可以分为以下几类:

  • MapReduce架构系统:如Hive,这类系统是在MapReduce计算框架上封装了一个SQL语义层,在运行过程中把SQL转换为MapReduce程序来执行
  • MPP架构系统:如Impala、Presto、Drill等,这类系统采用MPP(Massively Parallel Processing)架构,使用的是分布式查询引擎,而非MapReduce
  • 预计算系统:如Druid、Kylin等,这类系统主要特点是对数据进行预计算,并将结果保存,而在查询时直接获取相应结果值。

本文主要是对这些系统做了一个基本总结,并简单介绍了一些主流系统的架构以及处理流程。下表是按照时间顺序,对这些系统的一个概述,包括技术特点和主导公司等。

项目名称 时间点 技术特点 主导公司
Apache Hive 2008年进入Apache,2010年毕业 一款基于HDFS的MapReduce计算框架,提供类SQL的数据查询功能,本质是将SQL转换为MapReduce任务运行 初期由Facebook开发,后被各大公司广泛接受
Apache Spark 2010年进入Apache,2014年毕业 数据在内存中以RDD(Resilient Distributed Datasets)表示,DataFrame是其核心编程抽象,同时也支持交互式查询和流计算 Databricks
Cloudera Impala 2012年进入Apache,仍在孵化中 一款使用C/C++实现的MPP SQL查询引擎,使用HDFS作为存储,并支持列存 Cloudera
Apache Drill 2012年进入Apache,2014年毕业 以Google Dremel论文为基础,一个MPP数据查询引擎,支持schema free的交互式数据查询 MapR
Presto 2013年开源 基于内存的计算引擎,本身并不存储数据,支持跨数据源的级联查询 Facebook
Stinger Initiative 2013年 对Hive的性能优化和提升 Hortonworks
Apache Phoenix 2013年进入Apache,2014年5月毕业 构建在HBase上的一个SQL层 初期由Salesforce开发
Apache Tajo 2013年进入Apache,2014年5月毕业 基于Hadoop的数据仓库和SQL数据查询执行引擎 由Database Lab., Korea University开发
Apache Flink 2014年4月进入Apache,2014年12月毕业 流式的数据流执行引擎,基于流计算来模拟批计算,分别提供了流处理和批处理API Data Artisans
Apache Kylin 2014年11月进入Apache,2015年11月毕业 使用CUBE技术做多维数据预计算和聚合 初期由ebay开发,现由Kyligence主导
Apache HAWQ 2015年进入Apache,2018年5月毕业 Hadoop原始大规模并行SQL分析引擎,支持ACID事物特性 Hortonworks
Apache Trafodion 2015年进入Apache,孵化中 构建在HBase上的一个SQL层 HP实验室

Apache Hive

Apache Hive是Hadoop生态系统中最早的SQL引擎,它可以将结构化数据文件映射为一张数据库表,并提供类SQL查询功能。Hive本质上是在MapReduce计算框架上封装了一个SQL语义层,并在运行过程中把SQL转换为MapReduce程序来执行。

Hive通过用户交互接口接收SQL后,其Driver结合元数据将SQL翻译成MapReduce程序,并提交到Hadoop中执行,最后将执行结果输出,其架构如下图所示:

undefined

主要组成部分包括:

  • user interface:即用户接口,包含CLI(命令行),JDBC/ODBC等
  • Metastore:即元数据,包括表名、表的数据所在目录等;默认元数据存储在自带的derby数据库中,推荐使用MySQL
  • Driver:即驱动器,包含以下几个组件:
    (1) 解析器(SQL Parser):将SQL转换成抽象语法树(AST),并对AST进行语法分析。

(2) 编译器(Compiler):将AST编译生成逻辑执行计划。
(3) 优化器(Query Optimizer):对逻辑执行计划进行优化。
(4) 执行器(Execution):把逻辑执行计划转换成可以运行的物理计划。

Hive提供的类SQL查询功能避免了开发人员书写复杂的MapReduce程序,极大的简化了MapReduce程序的开发,大大减少了相应的学习成本。随着技术的不断进步,Hive的执行引擎也不断发展,尤其是有了Tez之后,其性能有了很大的改进。不过,其缺点依旧很明显,即处理速度慢,比较适合运行在批处理场景中,而不适合交互式查询等对时延要求高的场景中。

Apache Spark

Spark是一个通用的大数据计算框架,期望使用一个技术栈来解决大数据领域包括批处理、流计算、交互式查询、图计算和机器学习在内的各种计算任务,其软件栈如下图所示:

undefined

其中的Spark SQL组件是一个用于处理结构化数据的组件,它吸收了一个叫Shark(Hive-on-Spark)的项目。Spark SQL中最重要的一个概念就是DataFrame,它是带有Shema信息的RDD,类似于传统数据库中的二维表格。Spark SQL支持将多种外部数据源的数据转化为DataFrame,包括Json、Parquet等,并可以通过将其注册为临时表,然后使用SQL来处理和分析这些数据。Spark SQL的运行流程包含以下几步,如图所示:

undefined

包含以下几个步骤:

  1. SQL语句经过SqlParser解析成UnresolvedLogicalPlan。
  2. Analyzer结合catalog进行绑定,生成LogicalPlan。
  3. Optimizer对LogicalPlan优化,生成OptimizedLogicalPlan。
  4. SparkPlan将OptimizedLogicalPlan转换成PhysicalPlan。
  5. prepareForExecution()将PhysicalPlan转换成executedPhysicalPlan。
  6. PhysicalPlan执行得到最终结果RDD。

传统的MapReduce程序中Map和Reduce阶段的结果都要写磁盘,这大大降低了系统性能。Spark使用RDD作为基本数据结构,数据常驻内存,所以计算速度得到了很大提高。但是当内存不足时,其计算速度会大大降低,甚至容易出现OOM错误。

Apache Impala

Apache Impala是一款基于HDFS/HBase的MPP查询引擎,其架构如下图所示:

undefined

主要组成部分包括:

  • Impalad: 即Impala Daemon(Impala守护进程);它运行在集群的每个node上,负责接收客户端的查询请求,对查询进行并行化处理。其中接收查询请求的Impalad为Coordinator,Coordinator对查询语句处理后生成执行计划,再把执行计划分发给具有相应数据的其它Impalad执行,其他Impalad执行完成后,把结果发送回
    Coordinator,由Coordinator构建最终结果,并返回给客户端。另外,Impalad进程也会和Statusstore通信以确认哪些Impalad是可以正常工作的。
  • Statestore: 负责跟踪和检查Impalad健康状态的进程,由statestored进程表示;它负责处理Impalad的注册订阅,并且和各个Impalad进程保持心跳链接。
  • CLI: 提供给用户查询使用的命令行工具(Impala Shell使用python实现),同时Impala还提供了Hue,JDBC, ODBC使用接口。

Impala没有使用MapReduce计算框架,而是使用与商用并行关系数据库中类似的分布式查询引擎,并且Impala的中间结果不写入磁盘,而是通过网络以流的形式传递,这大大降低了IO开销,因而Impala的查询速度非常快。但是Impala缺点也很明显,如对用户自定义函数支持不好、不支持Transforms、不支持查询期的容错等。

Apache Drill

Apache Drill是一个分布式的MPP SQL引擎,是开源版本的Google Dremel。它支持对本地文件、HDFS、HBASE等数据进行数据查询,也支持对如JSON等schema-free的数据进行查询,其架构如下图所示:

undefined

从上图可以看到,Drill的核心是DrillBit,它主要负责接收客户端的请求,处理查询,并将结果返回给客户端。 Drill的查询流程包括以下步骤:

  1. drill客户端发起查询,任意DrilBit都可以接受来自客户端的查询。
  2. 收到请求的DrillBit成为驱动节点(Foreman),对查询进行分析优化生成执行计划,之后将执行计划划分成各个片段,并确定合适的节点来执行。
  3. 各个节点执行查询片段,并将结果返回给驱动节点。
  4. 驱动节点将结果返回给客户端。

Presto

Presto是一个分布式的MPP查询引擎,支持多种数据源,包括Hive、RDBMS、Redis等,并且可以跨数据源查询。Presto的基本架构如下图所示:

undefined

主要组成部分包括:

  • coodinator:用于解析查询SQL,生成执行计划,并分发给worker执行。
  • discovery server:worker上线后,向discovery server注册。coodinator分发任务前,需要向discovery server获取可以正常工作worker列表。
  • worker:具体执行任务的工作节点。

Apache Phoenix

Apache Phoenix是一个运行在HBase上的SQL框架,其本质是用Java写的基于JDBC API操作HBase的开源SQL引擎,通过Phoenix可以像使用MySQL等关系型数据库一样操作HBase中的表。Apache Phoenix支持ACID事务功能的标准SQL,它将SQL编译成原生HBase的scan语句,其架构如下图所示:

undefined

从上图可以看到:

  • Phoenix的JDBC driver是在HBase的client端。
  • Phoenix在HBase的RegionServer上。

Apache Kylin

Apache Kylin是一个开源的分布式分析引擎,提供Hadoop/Spark之上的SQL查询接口及多维分析(OLAP)能力。Kylin的核心是预计算,即对可能用到的度量进行预计算,并将结果保存为Cube以便查询时直接访问。Kylin的架构如下图所示:

undefined

主要组成部分包括:

  • 离线构建部分:根据元数据的定义,从数据源(如Hive)抽取数据,并通过MapReduce Job构建Cube。构建后的Cube保存在HBase中。
  • 在线查询部分:用户通过RESTful API、JDBC/ODBC等接口提交SQL,REST服务把SQL交给查询引擎处理。查询引擎解析SQL,生成逻辑执行计划,之后将其转化为基于Cubde物理执行计划,最后读取预计算生成的Cube并返回结果。

Apache Flink

Apache Flink是一个面向分布式数据流处理和批量数据处理的开源计算平台,它能够基于同一个Flink运行时提供流处理和批处理两种类型应用的功能。区别于其他流处理系统,Flink作为流处理时,把输入数据流看做是无界的,而批处理被作为一种特殊的流处理,只是它的输入数据流被定义为有界的。

基于同一个Flink运行时(Flink Runtime),Flink分别提供了流处理和批处理API,为了实现API层流与批的统一,Flink提供了一种关系型API,即Table & SQL API。

undefined

Apache HAWQ

Apache HAWQ的全称是Hadoop With Query,是一个Hadoop原生的MPP SQL引擎。HAWQ能直接在HDFS上读写数据,而不需要connector,并支持ACID事务特性,其架构如下图所示:

undefined

主要组成部分包括:

  • HAWQ master:负责处理客户端提交的SQL,解析优化后向集群Segment节点下发查询,合并从各Segemt节点返回的结果,并返回最终结果给客户端。HAWQ master内部由HAWQ Resource Manager,HAWQ Catalog Service,HAWQ Fault Tolerance Service,HAWQ Dispatcher等组件组成。HAWQ master还需要维护global system catalog,global system catalog是系统表的集合,其中包含了HAWQ集群的元数据信息。
  • HAWQ segment:集群的计算节点,本身不存储任何数据,所有数据都存储在HDFS上。HAWQ master在分派SQL请求给Segment时会附带相关的元数据信息,元数据信息包含了表的HDFS URL,Segment通过HDFS URL访问需要处理的数据。
  • PXF agent:PXF(Pivotal eXtension Framework)的服务。PXF是一个允许HAWQ访问外部系统数据的可扩展框架,其中内置了访问HDFS文件,HBase表以及Hive表的连接器,PXF还可以通过和HCatalog集成来直接访问Hive表。

结束语

SQL-on-Hadoop系统经过了若干年的发展,已经有了很大的提高,但是目前各个系统仍然在不断完善提高,例如:

  • 执行计划方面:更强的优化器
  • 执行效率方面:支持code generation、vectorization等
  • 存储格式方面:支持更高效列存等

未来也会出现更多技术、更多系统。本文主要介绍了目前几大开源的SQL-on-Hadoop系统及其架构,包括Hive、Spark、Presto、Drill等。

参考

Tutorial: SQL-on-Hadoop Systems
SQL 引擎年度总结
六大主流开源SQL引擎总结
apache hive
Hive架构
Spark SQL: Relational data processing in Spark
Impala架构和工作原理
Apache Drill
Apache Drill介绍
Presto实现原理和美团的使用实践
Phoenix overview
Apache kylin
Apache Flink
Flink原理与实现
HAWQ: A massively parallel processing SQL engine in hadoop
HAWQ技术解析-基本架构

猜你喜欢

转载自yq.aliyun.com/articles/690141