SQL on Hadoop 技术分析(二)

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

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

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等等也同样有自己的查询优化器,这些技术未来将会变得越来越成熟,越来越方便用户的使用,相应的,用户将会变得更加容易,更加方便的从自己的大数据中挖掘出有价值的商业信息。

原文发布于微信公众号 - 大数据和云计算技术(jiezhu2007)

原文发表时间:2016-07-18

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏WeTest质量开放平台团队的专栏

用 ElasticSearch 搭建自己的搜索和分析引擎

ElasticSearch 作为 一个搜索引擎的轮子。除去常规的全文检索功能之外,它还具有基础的统计分析功能(最常见的就是聚合),这也让它变得更加强大和实用。 ...

2.7K0
来自专栏java一日一条

有经验的Java开发者和架构师容易犯的10个错误(上)

首先允许我们问一个严肃的问题?为什么Java初学者能够方便的从网上找到相对应的开发建议呢?每当我去网上搜索想要的建议的时候,我总是能发现一 大堆是关于基本入门的...

502
来自专栏Java与Android技术栈

响应式和函数式,两个容易混淆的概念

传统的编程方式,是顺序执行的,上一个任务没有完成的话需要等待直至完成之后才会执行下一个任务。无论是提升机器的性能还是代码的性能,本质上都需要依赖上一个任务的完成...

711
来自专栏牛客网

网易云音乐Java面经(共三面)

【每日一语】很多人都无从得知自己的天赋,因为找不到相信他们的老师。于是他们深信自己很笨。——《心灵捕手》

371
来自专栏微服务生态

由学习《软件设计重构》所想到的代码review(一)

对于一个程序员来讲如何来最直接的来衡量他的技术能力和产出呢?我想最直观的作法是看他的代码编写能力,就拿我经常接触的一些程序员来看,他们买了很多技术重构类书籍,但...

553
来自专栏Albert陈凯

Hbase二级索引

二级索引与索引Join是多数业务系统要求存储引擎提供的基本特性,RDBMS早已支持,NOSQL阵营也在摸索着符合自身特点的最佳解决方案。这篇文章会以Hbase做...

3134
来自专栏祝威廉

Spark Streaming Crash 如何保证Exactly Once Semantics

其实这次写Spark Streaming相关的内容,主要是解决在其使用过程中大家真正关心的一些问题。我觉得应该有两块:

511
来自专栏谢慧志的专栏

数据倾斜解决方法总结

在使用Spark、Hive的过程中经常会碰到数据倾斜的问题,本文会持续记录实际工作中碰到的这些问题以及具体解决方案。

2.2K0
来自专栏程序人生

重构:撰写合格的代码

在「代码重构之道」里,我犯了个懒,讨论了什么情况下需要考虑重构,以及工具和方法来促进重构,但对如何重构代码本身,或者说:如何把烂代码转化成好代码,或者至少是合格...

3378
来自专栏微信公众号:Java团长

看似简单但容易忽视的编程常识

这些年写了很多的代码、也读过很多的人写的代码,这几年,写代码的机会越来越少,但是每次写代码,感觉需要思考的东西越来越多,好的代码确实难能可贵,在国内业界中,好的...

763

扫描关注云+社区