开源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等,这类系统主要特点是对数据进行预计算,并将结果保存,而在查询时直接获取相应结果值
本文主要是对这些系统做了一个基本总结,并简单介绍了一些主流系统的架构以及处理流程。下表是按照时间顺序,对这些系统的一个概述,包括技术特点和主导公司等。
开源SQL-on-Hadoop系统一览

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

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

开源SQL-on-Hadoop系统一览

主要组成部分包括:

user interface:即用户接口,包含CLI(命令行),JDBC/ODBC等
Metastore:即元数据,包括表名、表的数据所在目录等;默认元数据存储在自带的derby数据库中,推荐使用MySQL
Driver:即驱动器,包含以下几个组件:

解析器(SQL Parser):将SQL转换成抽象语法树(AST),并对AST进行语法分析
编译器(Compiler):将AST编译生成逻辑执行计划
优化器(Query Optimizer):对逻辑执行计划进行优化
执行器(Execution):把逻辑执行计划转换成可以运行的物理计划
Hive提供的类SQL查询功能避免了开发人员书写复杂的MapReduce程序,极大的简化了MapReduce程序的开发,大大减少了相应的学习成本。随着技术的不断进步,Hive的执行引擎也不断发展,尤其是有了Tez之后,其性能有了很大的改进。不过,其不足依旧很明显,即处理速度慢,因而比较适合运行在批处理场景中,而不适合交互式查询等对时延要求高的场景中。

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

开源SQL-on-Hadoop系统一览

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

开源SQL-on-Hadoop系统一览

包含以下几个步骤:

SQL语句经过SqlParser解析成UnresolvedLogicalPlan
Analyzer结合catalog进行绑定,生成LogicalPlan
Optimizer对LogicalPlan优化,生成OptimizedLogicalPlan
SparkPlan将OptimizedLogicalPlan转换成PhysicalPlan
prepareForExecution()将PhysicalPlan转换成executedPhysicalPlan
PhysicalPlan执行得到最终结果RDD
传统的MapReduce程序中Map和Reduce阶段的结果都要写磁盘,这大大降低了系统性能。Spark使用RDD作为基本数据结构,数据常驻内存,所以计算速度得到了很大提高。但是当内存不足时,其计算速度会大大降低,甚至容易出现OOM错误。

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

开源SQL-on-Hadoop系统一览

主要组成部分包括:

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的数据进行查询,其架构如下图所示:

开源SQL-on-Hadoop系统一览

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

drill客户端发起查询,任意DrilBit都可以接受来自客户端的查询
收到请求的DrillBit成为驱动节点(Foreman),对查询进行分析优化生成执行计划,之后将执行计划划分成各个片段,并确定合适的节点来执行
各个节点执行查询片段,并将结果返回给驱动节点
驱动节点将结果返回给客户端
Presto
Presto是一个分布式的MPP查询引擎,支持多种数据源,包括Hive、RDBMS、Redis等,并且可以跨数据源查询。Presto的基本架构如下图所示:

开源SQL-on-Hadoop系统一览

主要组成部分包括:

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语句,其架构如下图所示:

开源SQL-on-Hadoop系统一览

从上图可以看到:

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

开源SQL-on-Hadoop系统一览

主要组成部分包括:

离线构建部分:根据元数据的定义,从数据源(如Hive)抽取数据,并通过MapReduce Job构建Cube,构建后的Cube保存在HBase中
在线查询部分:用户通过RESTful API、JDBC/ODBC等接口提交SQL,REST服务把SQL交给查询引擎处理。查询引擎解析SQL,生成逻辑执行计划,之后将其转化为基于Cube的物理执行计划,最后读取预计算生成的Cube并返回结果
Apache Flink
Apache Flink是一个面向分布式数据流处理和批量数据处理的开源计算平台,它能够基于同一个Flink运行时提供流处理和批处理两种类型应用的功能。区别于其他流处理系统,Flink作为流处理时,把输入数据流看做是无界的,而批处理被作为一种特殊的流处理,只是它的输入数据流被定义为有界的。

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

开源SQL-on-Hadoop系统一览

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

开源SQL-on-Hadoop系统一览

主要组成部分包括:

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等。

本文作者:勿烦

阅读原文

本文为云栖社区原创内容,未经允许不得转载。

相关推荐