森哥大作,接上一篇:SQL on Hadoop技术分析(一)

本篇继续分析SQL on Hadoop的相关技术,本次分析的重点是查询优化器(技术上的名词叫SQL Parser),在SQL on Hadoop技术中有着非常重要的地位,一次查询SQL下来,SQL Parser分析SQL词法,语法,最终生成执行计划,下发给各个节点执行,SQL的执行的过程快慢,跟生成的执行计划的好坏,有直接的关系,下面以目前业界SQL onHadoop 使用的比较多的组件Impala、HAWQ,Spark SQL来介绍下它们的查询优化器技术。

Impala:

SQL支持度:

支持SQL92中的大部分select语句, 以及SQL2003标准中的分析函数。 不支持DELETE和UPDATE, 但是支持批量装载数据(insert into select, LOADDATA) 和批量删除数据(drop partition)。除此之外, 用户也可直接操作HDFS文件实现数据装载和清理。

查询执行:

impalad分为frontend和backend两个层次, frontend用java实现(通过JNI嵌入impalad), 负责查询计划生成, 而backend用C++实现, 负责查询执行。Impala的查询流程如下图所示

frontend生成查询计划分为两个阶段:(1)生成单机查询计划,单机执行计划与关系数据库执行计划相同,所用查询优化方法也类似。(2)生成分布式查询计划。根据单机执行计划, 生成真正可执行的分布式执行计划,降低数据移动, 尽量把数据和计算放在一起。

下面以一个三表join的例子生成的执行计划来说明下Impala组件的在SQL执行过程中的相关的性能优化的技术点。

上图是SQL查询例子, 该SQL的目标是在三表join的基础上算聚集, 并按照聚集列排序取topN。 impala的查询优化器支持代价模型: 利用表和分区的cardinality,每列的distinct值个数等统计数据, impala可估算执行计划代价, 并生成较优的执行计划。上图左边是frontend查询优化器生成的单机查询计划, 与传统关系数据库不同, 单机查询计划不能直接执行, 必须转换成如图右半部分所示的分布式查询计划。该分布式查询计划共分成6个segment(图中彩色无边框圆角矩形),每个segment是可以被单台服务器独立执行的计划子树。

impala支持两种分布式join方式, 表广播和哈希重分布:表广播方式保持一个表的数据不动,将另一个表广播到所有相关节点(图中t3); 哈希重分布的原理是根据join字段哈希值重新分布两张表数据(譬如图中t1和t2)。分布式计划中的聚集函数分拆为两个阶段执行。第一步针对本地数据进行分组聚合(Pre-AGG)以降低数据量, 并进行数据重分步, 第二步, 进一步汇总之前的聚集结果(mergeAgg)计算出最终结果。与聚集函数类似, topN也是分为两个阶段执行, (1)本地排序取topN,以降低数据量; (2)merge sort得到最终topN结果。

Backend从frontend接收plan segment并执行, 执行性能非常关键,impala采取的查询性能优化措施有:

1) 向量执行。 一次getNext处理一批记录, 多个操作符可以做pipeline。

2)LLVM编译执行, CPU密集型查询效率提升几倍以上,具体看执行的SQL查询场景。

3)IO本地化。 利用HDFS short-circuit local read功能,实现本地文件读取

4)Parquet列存,充分利用列式存储的优势。

HAWQ:

HAWQ支持Apache Hadoop原生HDFS的SQL大规模并行引擎(MPP SQL) ,跟Impala组件类似,也是一种采用类似MPP DB技术实现的。HAWQ是基于GreenplumMPP数据库技术实现的,同样采用了Greenplum数据库的SQL查询优化器,下面以运行于HAWQ 解析器中的SQL查询分析HAWQ的查询机制,如下图所示:

HAWQ数据库层会对SQL查询加以解析并最终作用于HDFS,一旦查询请求出现,我们会对它进行解析并生成解析树,接下来发生的情况 非常特殊。HAWQ获取生成的解析树并从通用目录服务中获取元数据。HAWQ会根据底层Hadoop集群的运行状态获取成本模型,这套模型了解存储资源性能、掌握各项数据的访问成本以及数据的专有排列方式。根据上述信息,它会发送一套资源模型,并以此为指导生成查询执行规划,如下图所示:

SQL查询进入能与HDFS顺利交互的并行优化器,整个流程展示了一项重大内容,基于成本模型(Cost Model)的优化方案。之后生成的查询计划如下图所示:

接下来HAWQ的主节点Master下发执行计划给Query Executor执行,查询执行器利用HDFS NameNode将工作内容传递至HAWQ数据库的使用空间之中,如下图所示:图片

HAWQ的秘密在于这套数据库层实际是一条动态传输途径,其中结合了Greenplum作为并行关系类数据库(主要作为PostgreSQL的替代方案)所准备的多项不同技术,如下图所示:
工作调度机制(与Hadoop中的NameNode及JobTracker有所区别),其作用是以最优方式对查询进行安排及部署。在Hadoop NameNode所引导的恰当数据块中加以执行之后,这些查询会返回至NameNode处,查询结果则被提交给发出SQL查询的软件。这种动态传输途径使HAWQ在性能上获得了极其可观的优势,它所带来的SQL查询处理速度能够达到Hive等同样支持HDFS方案的十倍甚至六百倍。另外,如此规模的性能提升也成功将Hadoop从原本的批处理式系统转化为交互式系统。

Spark SQL
动态传输途径算是一套专为查询请求打造的
工作调度机制(与Hadoop中的NameNode及JobTracker有所区别),其作用是以最优方式对查询进行安排及部署。在Hadoop NameNode所引导的恰当数据块中加以执行之后,这些查询会返回至NameNode处,查询结果则被提交给发出SQL查询的软件。这种动态传输途径使HAWQ在性能上获得了极其可观的优势,它所带来的SQL查询处理速度能够达到Hive等同样支持HDFS方案的十倍甚至六百倍。另外,如此规模的性能提升也成功将Hadoop从原本的批处理式系统转化为交互式系统。

Spark SQL

SparkSQL是Spark组件中的一部分,Spark SQL的查询优化器项目叫Spark Catalyst,在Spark SQL担任的角色是优化器,Spark SQL在2015年sigmod上发了一篇论文。论文中对查询优化器做了比较详细的介绍,先看下SparkSQL与Spark交互的架构图,如下图所示:

在论文中看到查询优化器中介绍的各个角色,分别为Parser、Analyzer、Optimizer、Planner

同样,在论文中已经提及到了这些角色的作用, 其中parser负责把用户输入的SQL语句进行解释,转变为Unresolved Logical Plan。Unresolved Logical Plan中会包含SQL语句中出现的变量名和表名,这些词素暂时来讲都会被标记为unresolved,即“不知道是否存在这个表”或“不知道表中是否有这个字段”。这个时候轮到Analyzer登场,它利用Catalog提供的信息, 对所有这些unresolved的词素进行resolve,并在resolve失败时抛出错误。结束后便得到了Analyzed Logical Plan。接下来轮到Optimizer, 它使用rule-based的优化规则对传入的Analyzed Logical Plan进行优化,得到一个OptimizedLogical Plan。最终Optimized Logical Plan传入到Planner, 生成物理执行计划,得到Physical Plan。具体流程入如下图所示:
同样Spark SQL采用的性能优化措施还有数据的存储格式(比如Parquet格式,还有华为研发并开源的CarbonData数据格式),Codegen等技术,另外最新的Spark2.0版本对Catalyst有进一步优化提升,具体可以看Spark2.0的官网上的介绍。

总结:

本文主要介绍了几种常用的SQL onHadoop组件的查询优化器的相关技术,其它组件如Apache Drill等等也同样有自己的查询优化器,这些技术未来将会变得越来越成熟,越来越方便用户的使用,相应的,用户将会变得更加容易,更加方便的从自己的大数据中挖掘出有价值的商业信息。

©著作权归作者所有:来自51CTO博客作者mob604756ec296f的原创作品,如需转载,请注明出处,否则将追究法律责任

更多相关文章

  1. Excel按区间查询,大咖有句悄悄话
  2. Hive高级优化 | 面试及调优必读
  3. 带聚光灯的Excel数据查询,简单到没朋友
  4. Structured Streaming VS Flink
  5. Mac 安装Homebrew慢的问题解决
  6. Spark SQL从入门到精通
  7. 1.3 Ansible 整体架构图
  8. 2.0 Ansible Ad-Hoc命令
  9. ThinkPHP框架:数据库链表查询和导航渲染(导航数据递归生成)

随机推荐

  1. php验证图片不显示
  2. php获取今天是星期几
  3. TCP 的连接建立与关闭状态及数据传输通信
  4. PHP 开发中涉及到emoji表情的几种处理方
  5. PHP 框架中的日志系统
  6. PHP 实现简易的汉字验证码的思路
  7. PHP+Redis发布订阅
  8. php检查数组下标是否存在
  9. php 与 nginx 的两种处理方式
  10. PHP运算符知识点整理