Spark SQL原理及实战
一、Spark SQL的发展
1、spark SQL和shark
SparkSQL的前身是Shark,给熟悉RDBMS但又不理解MapReduce的技术人员提供快速上手的工具,Hive应运而生,它是当时唯一运行在Hadoop上的SQL-on-Hadoop工具。但是MapReduce计算过程中大量的中间磁盘落地过程消耗了大量的I/O,降低的运行效率,为了提高SQL-on-Hadoop的效率,大量的SQL-on-Hadoop工具开始产生,其中表现较为突出的是:
1、MapR的Drill
2、Cloudera的Impala
3、Shark
Shark对于Hive的太多依赖(如采用Hive的语法解析器、查询优化器等等),但SparkSQL摆脱了对Hive的依赖性,无论在数据兼容、性能优化、组件扩展方面都得到了极大的方便。
1、数据兼容方面 不但兼容Hive,还可以从RDD、parquet文件、JSON文件中获取数据,未来版本甚至支持获取RDBMS数据以及cassandra等NOSQL数据;
2、性能优化方面 除了采取In-Memory Columnar Storage、byte-code generation等优化技术外、将会引进Cost Model对查询进行动态评估、获取最佳物理计划等等;
3、组件扩展方面 无论是SQL的语法解析器、分析器还是优化器都可以重新定义,进行扩展;
2、Spark SQL的性能
1)内存列存储(In-Memory Columnar Storage)
对于内存列存储来说,将所有原生数据类型的列采用原生数组来存储,将Hive支持的复杂数据类型(如array、map等)先序列化后并接成一个字节数组来存储。这样,每个列创建一个JVM对象,从而导致可以快速地GC和紧凑的数据存储。额外的,还可以用低廉CPU开销的高效压缩方法来降低内存开销。更有趣的是,对于分析查询中频繁使用的聚合特定列,性能会得到很大的提高,原因就是这些列的数据放在一起,更容易读入内存进行计算。
2)字节码生成技术(bytecode generation,即CG)
在数据库查询中有个昂贵的操作就是查询语句中的表达式,主要是由JVM的内存模型引起的。如SELECT a+b FROM table,这个查询里如果采用通用的SQL语法途径去处理,会先生成一个表达树,会多次设计虚函数的调用,这会打断CPU的正常流水线处理,减缓执行速度。
spark -1.1.0在catalyst模块的expressions增加了codegen模块,如果使用动态字节码生成技术,Spark SQL在执行物理计划时,会对匹配的表达式采用特定的代码动态编译,然后运行。
SQL查询的CG优化
3、Scala代码的优化
Spark SQL在使用Scala语言编写代码时,应尽量避免容易GC的低效代码。尽管增加了编写代码的难度,但对于用户来说,还是使用了统一的接口,让开发在使用上更加容易。
Scala代码的优化
二、Spark SQL运行架构
SparkSQL有两个分支,sqlContext和hiveContext,sqlContext现在只支持SQL语法解析器(SQL-92语法);hiveContext现在支持SQL语法解析器和hivesql语法解析器,默认为hiveSQL语法解析器,用户可以通过配置切换成SQL语法解析器,来运行hiveSQL不支持的语法。
1)sqlContext具体的执行过程如下:
1、SQL | HQL语句经过SqlParse解析成UnresolvedLogicalPlan;
2、使用analyzer结合数据数据字典(catalog)进行绑定,生成resolvedLogicalPlan;在这个过程中,Catalog提取出SchemRDD,并注册类似case class的对象,然后把表注册进内存中。
3、Analyzed Logical Plan经过Catalyst Optimizer优化器优化处理后,生成Optimized Logical Plan,该过程完成以后,以下的部分在spark core中完成。
4、Optimized Logical Plan的结果交给SparkPlanner,然后SparkPlanner处理后交个PhysicalPlan,经过该过程后生成Spark Plan
5、使用SparkPlan将LogicalPlan转换成PhysicalPlan;
6、使用prepareForExecution()将PhysicalPlan转换成可执行物理计划;
7、使用execute()执行可执行物理计划;
8、生成SchemaRDD。
在整个运行过程中涉及到多个SparkSQL的组件,如SqlParse、analyzer、optimizer、SparkPlan等等
2)hiveContext总的一个过程如下图所示:
1、SQL语句经过HiveQl.parseSql解析成Unresolved LogicalPlan,在这个解析过程中对hiveql语句使用getAst()获取AST树,然后再进行解析;
2、使用analyzer结合数据hive源数据Metastore(新的catalog)进行绑定,生成resolved LogicalPlan;
3、使用optimizer对resolved LogicalPlan进行优化,生成optimized LogicalPlan,优化前使用了ExtractPythonUdfs(catalog.PreInsertionCasts(catalog.CreateTables(analyzed)))进行预处理;
4、使用hivePlanner将LogicalPlan转换成PhysicalPlan;
5、使用prepareForExecution()将PhysicalPlan转换成可执行物理计划;
6、使用execute()执行可执行物理计划;
7、执行后,使用map(_.copy)将结果导入SchemaRDD。
hiveContext执行过程
三、catalyst优化器
SparkSQL1.1.0总体上由四个模块组成:core、catalyst、hive、hive-Thriftserver:
1)core处理数据的输入输出,从不同的数据源获取数据(RDD、Parquet、json等),将查询结果输出成schemaRDD;
2)catalyst处理查询语句的整个处理过程,包括解析、绑定、优化、物理计划等,说其是优化器,还不如说是查询引擎;
3)hive对hive数据的处理
4)hive-ThriftServer提供CLI(命令行界面)和JDBC/ODBC接口
catalyst处于最核心的部分,其性能优劣将影响整体的性能。
从上图看,catalyst主要的实现组件有:
1)sqlParse,完成sql语句的语法解析功能,目前只提供了一个简单的sql解析器;
2)Analyzer,主要完成绑定工作,将不同来源的Unresolved LogicalPlan和数据元数据(如hive metastore、Schema catalog)进行绑定,生成resolved LogicalPlan;
3)optimizer对resolved LogicalPlan进行优化,生成optimized LogicalPlan;
4)Planner将LogicalPlan转换成PhysicalPlan;
5)CostModel,主要根据过去的性能统计数据,选择最佳的物理执行计划
转载http://www.cnblogs.com/shishanyuan/p/4723604.html?utm_source=tuicool