SparkSQL的解析详解
SparkSQL继承自Hive的接口,由于hive是基于MapReduce进行计算的,在计算过程中大量的中间数据要落地于磁盘,从而消耗了大量的I/O,降低了运行的效率,从而基于内存运算的SparkSQL应运而生。
首先说下传统数据库的解析,传统数据库的解析过程是按Rusult、Data Source、Operation的次序来解析的。传统数据库先将读入的SQL语句进行解析,分辨出SQL语句中哪些词是关键字(如select,from,where),哪些是表达式,哪些是Projection,哪些是Data Source等等。进一步判断SQL语句是否规范,不规范就报错,规范则按照下一步过程绑定(Bind)。过程绑定是将SQL语句和数据库的数据字典(列,表,视图等)进行绑定,如果相关的Projection、Data Source等都存在,就表示这个SQL语句是可以执行的。在执行过程中,有时候甚至不需要读取物理表就可以返回结果,比如重新运行刚运行过的SQL语句,直接从数据库的缓冲池中获取返回结果。 在数据库解析的过程中SQL语句时,将会把SQL语句转化成一个树形结构来进行处理,会形成一个或含有多个节点(TreeNode)的Tree,然后再后续的处理政对该Tree进行一系列的操作。
Spark SQL对SQL语句的处理和关系数据库对SQL语句的解析采用了类似的方法,首先会将SQL语句进行解析,然后形成一个Tree,后续如绑定、优化等处理过程都是对Tree的操作,而操作方法是采用Rule,通过模式匹配,对不同类型的节点采用不同的操作。SparkSQL有两个分支,sqlContext和hiveContext。sqlContext现在只支持SQL语法解析器(Catalyst),hiveContext支持SQL语法和HiveContext语法解析器。
sqlContext的解析过程:
(1)SQL语句经过SqlParse解析成Unresolved LogicalPlan。
(2)使用analyzer结合数据字典(cataqlog)进行绑定,生成resolved LogicalPlan。
(3)使用optimizer对resolved LogicalPlan进行优化,生成optimized LogicalPlan。
(4)使用SparkPlan将LogicalPlan转换成PhysicalPlan。
(5)使用prepareForExecution()将PhysicalPlan转换成可执行物理计划。
(6)使用execute()执行物理计划。
(7)生成SchemaRDD。
然而并没有什么卵用,catalyst解析做的有些简陋,很多不支持,所以在写程序的时候,还是声明的hiveContext对象。
hiveContext的解析过程:
(1)SQL语句经过HiveQl.parseSql解析成了Unresolved LogicalPlan。
(2)使用analyzer结合hive的metastore进行绑定,生成resolved LogicalPlan。
(3)使用optimizer对resolved LogicalPlan进行优化,生成optimized LogicalPlan。
(4)使用hivePlanner将LogicalPlan转换成PhysicalPlan。
(5)shiyong prepareForExecution()将PhysicalPlan转换成可执行物理计划。
(6)使用execute()执行可执行物理计划。
(7)执行后,使用map(_.copy)将结果导入SchemaRDD。 (最终转化为RDD)