开源SQL-on-Hadoop系统一览

19次阅读

共计 4775 个字符,预计需要花费 12 分钟才能阅读完成。

引言查询分析是大数据要解决的核心问题之一,而 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 HiveApache Hive 是 Hadoop 生态系统中最早的 SQL 引擎,它可以将结构化数据文件映射为一张数据库表,并提供类 SQL 查询功能。Hive 本质上是在 MapReduce 计算框架上封装了一个 SQL 语义层,并在运行过程中把 SQL 转换为 MapReduce 程序来执行。
Hive 通过用户交互接口接收 SQL 后,其 Driver 结合元数据将 SQL 翻译成 MapReduce 程序,并提交到 Hadoop 中执行,最后将执行结果输出,其架构如下图所示:

主要组成部分包括:
user interface:即用户接口,包含 CLI(命令行),JDBC/ODBC 等 Metastore:即元数据,包括表名、表的数据所在目录等;默认元数据存储在自带的 derby 数据库中,推荐使用 MySQLDriver:即驱动器,包含以下几个组件:
解析器 (SQL Parser):将 SQL 转换成抽象语法树 (AST),并对 AST 进行语法分析编译器 (Compiler):将 AST 编译生成逻辑执行计划优化器 (Query Optimizer):对逻辑执行计划进行优化执行器 (Execution):把逻辑执行计划转换成可以运行的物理计划 Hive 提供的类 SQL 查询功能避免了开发人员书写复杂的 MapReduce 程序, 极大的简化了 MapReduce 程序的开发,大大减少了相应的学习成本。随着技术的不断进步,Hive 的执行引擎也不断发展,尤其是有了 Tez 之后,其性能有了很大的改进。不过,其不足依旧很明显,即处理速度慢,因而比较适合运行在批处理场景中,而不适合交互式查询等对时延要求高的场景中。
Apache SparkSpark 是一个通用的大数据计算框架,期望使用一个技术栈来解决大数据领域包括批处理、流计算、交互式查询、图计算和机器学习在内的各种计算任务,其软件栈如下图所示:

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

包含以下几个步骤:
SQL 语句经过 SqlParser 解析成 UnresolvedLogicalPlanAnalyzer 结合 catalog 进行绑定, 生成 LogicalPlanOptimizer 对 LogicalPlan 优化, 生成 OptimizedLogicalPlanSparkPlan 将 OptimizedLogicalPlan 转换成 PhysicalPlanprepareForExecution() 将 PhysicalPlan 转换成 executedPhysicalPlanPhysicalPlan 执行得到最终结果 RDD 传统的 MapReduce 程序中 Map 和 Reduce 阶段的结果都要写磁盘,这大大降低了系统性能。Spark 使用 RDD 作为基本数据结构,数据常驻内存,所以计算速度得到了很大提高。但是当内存不足时,其计算速度会大大降低,甚至容易出现 OOM 错误。
Apache ImpalaApache Impala 是一款基于 HDFS/HBase 的 MPP 查询引擎,其架构如下图所示:

主要组成部分包括:
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 DrillApache Drill 是一个分布式的 MPP SQL 引擎,是开源版本的 Google Dremel。它支持对本地文件、HDFS、HBASE 等数据进行数据查询,也支持对如 JSON 等 schema-free 的数据进行查询,其架构如下图所示:

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

主要组成部分包括:
coodinator:用于解析查询 SQL,生成执行计划,并分发给 worker 执行 discovery server:worker 上线后,向 discovery server 注册。coodinator 分发任务前,需要向 discovery server 获取可以正常工作 worker 列表 worker:具体执行任务的工作节点 Apache PhoenixApache Phoenix 是一个运行在 HBase 上的 SQL 框架,其本质是用 Java 写的基于 JDBC API 操作 HBase 的开源 SQL 引擎,通过 Phoenix 可以像使用 MySQL 等关系型数据库一样操作 HBase 中的表。Apache Phoenix 支持 ACID 事务功能的标准 SQL,它将 SQL 编译成原生 HBase 的 scan 语句,其架构如下图所示:

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

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

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

主要组成部分包括:
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 等。
本文作者:勿烦
阅读原文
本文为云栖社区原创内容,未经允许不得转载。

正文完
 0