Spark SQL的整体实现逻辑

1、sql语句的模块解析

   当我们写一个查询语句时,一般包含三个部分,select部分,from数据源部分,where限制条件部分,这三部分的内容在sql中有专门的名称:

当我们写sql时,如上图所示,在进行逻辑解析时会把sql分成三个部分,project,DataSource,Filter模块,当生成执行部分时又把他们称为:Result模块、

DataSource模块和Opertion模块。

那么在关系数据库中,当我们写完一个查询语句进行执行时,发生的过程如下图所示:

wKiom1fJKQCTVTrjAAD82tMpcQg075.png-wh_50

整个执行流程是:query -> Parse -> Bind -> Optimize -> Execute

1、写完sql查询语句,sql的查询引擎首先把我们的查询语句进行解析,也就是Parse过程,解析的过程是把我们写的查询语句进行分割,把project,DataSource和Filter三个部分解析出来从而形成一个逻辑解析tree,在解析的过程中还会检查我们的sql语法是否有错误,比如缺少指标字段、数据库中不包含这张数据表等。当发现有错误时立即停止解析,并报错。当顺利完成解析时,会进入到Bind过程。

2、Bind过程,通过单词我们可看出,这个过程是一个绑定的过程。为什么需要绑定过程?这个问题需要我们从软件实现的角度去思考,如果让我们来实现这个sql查询引擎,我们应该怎么做?他们采用的策略是首先把sql查询语句分割,分割不同的部分,再进行解析从而形成逻辑解析tree,然后需要知道我们需要取数据的数据表在哪里,需要哪些字段,执行什么逻辑,这些都保存在数据库的数据字典中,因此bind过程,其实就是把Parse过程后形成的逻辑解析tree,与数据库的数据字典绑定的过程。绑定后会形成一个执行tree,从而让程序知道表在哪里,需要什么字段等等

3、完成了Bind过程后,数据库查询引擎会提供几个查询执行计划,并且给出了查询执行计划的一些统计信息,既然提供了几个执行计划,那么有比较就有优劣,数据库会根据这些执行计划的统计信息选择一个最优的执行计划,因此这个过程是Optimize(优化)过程。

4、选择了一个最优的执行计划,那么就剩下最后一步执行Execute,最后执行的过程和我们解析的过程是不一样的,当我们知道执行的顺序,对我们以后写sql以及优化都是有很大的帮助的.执行查询后,他是先执行where部分,然后找到数据源之数据表,最后生成select的部分,我们的最终结果。执行的顺序是:operation->DataSource->Result

虽然以上部分对SparkSQL没有什么联系,但是知道这些,对我们理解SparkSQL还是很有帮助的。

2、SparkSQL框架的架构

要想对这个框架有一个清晰的认识,首先我们要弄清楚,我们为什么需要sparkSQL呢?个人建议一般情况下在写sql能够直接解决的问题就不要使用sparkSQL,如果想刻意使用sparkSQL,也不一定能够加快开发的进程。使用sparkSQL是为了解决一般用sql不能解决的复杂逻辑,使用编程语言的优势来解决问题。我们使用sparkSQL一般的流程如下图:

如上图所示,一般情况下分为两个部分:a、把数据读入到sparkSQL中,sparkSQL进行数据处理或者算法实现,然后再把处理后的数据输出到相应的输出源中。

1、同样我们也是从如果让我们开发,我们应该怎么做,需要考虑什么问题来思考这个问题。

     a、第一个问题是,数据源有几个,我们可能从哪些数据源读取数据?现在sparkSQL支持很多的数据源,比如:hive数据仓库、json文件,.txt,以及orc文件,同时现在还支持jdbc从关系数据库中取数据。功能很强大。

     b、还一个需要思考的问题是数据类型怎么映射啊?我们知道当我们从一个数据库表中读入数据时,我们定义的表结构的字段的类型和编程语言比如scala中的数据类型映射关系是怎样的一种映射关系?在sparkSQL中有一种来解决这个问题的方法,来实现数据表中的字段类型到编程语言数据类型的映射关系。这个以后详细介绍,先了解有这个问题就行。

     c、数据有了,那么在sparkSQL中我们应该怎么组织这些数据,需要什么样的数据结构呢,同时我们对这些数据都可以进行什么样的操作?sparkSQL采用的是DataFrame数据结构来组织读入到sparkSQL中的数据,DataFrame数据结构其实和数据库的表结构差不多,数据是按照行来进行存储,同是还有一个schema,就相当于数据库的表结构,记录着每一行数据属于哪个字段。

     d、当数据处理完以后,我们需要把数据放入到什么地方,并切以什么样的格式进行对应,这个a和b要解决的问题是相同的。

2、sparkSQL对于以上问题的实现逻辑也很明确,从上图已经很清楚,主要分为两个阶段,每个阶段都对应一个具体的类来实现。

   a、 对于第一个阶段,sparkSQL中存在两个类来解决这些问题:HiveContext,SQLContext,同时hiveContext继承了SQLContext的所有方法,同时又对其进行了扩展。因为我们知道, hive和mysql的查询还是有一定的差别的。HiveContext只是用来处理从hive数据仓库中读入数据的操作,SQLContext可以处理sparkSQL能够支持的剩下的所有的数据源。这两个类处理的粒度是限制在对数据的读写上,同时对表级别的操作上,比如,读入数据、缓存表、释放缓存表表、注册表、删除注册的表、返回表的结构等的操作。

  b、sparkSQL处理读入的数据,采用的是DataFrame中提供的方法。因为当我们把数据读入到sparkSQL中,这个数据就是DataFrame类型的。同时数据都是按照Row进行存储的。其中 DataFrame中提供了很多有用的方法。以后会细说。

 c、在spark1.6版本以后,又增加了一个类似于DataFrame的数据结构Dataset,增加此数据结构的目的是DataFrame有软肋,他只能处理按照Row进行存储的数据,并且只能使用DataFrame中提供的方法,我们只能使用一部分RDD提供的操作。实现Dataset的目的就是让我们能够像操作RDD一样来操作sparkSQL中的数据。

d、其中还有一些其他的类,但是现在在sparkSQL中最主要的就是上面的三个类,其他类以后碰到了会慢慢想清楚。

3、sparkSQL的hiveContext和SQLContext的运行原理

  hiveContext和SQLContext与我第一部分讲到的sql语句的模块解析实现的原理其实是一样的,采用了同样的逻辑过程,并且网上有好多讲这一块的,就直接粘贴复制啦!!

  sqlContext总的一个过程如下图所示:

1.SQL语句经过SqlParse解析成UnresolvedLogicalPlan;

2.使用analyzer结合数据数据字典(catalog)进行绑定,生成resolvedLogicalPlan;

3.使用optimizer对resolvedLogicalPlan进行优化,生成optimizedLogicalPlan;

4.使用SparkPlan将LogicalPlan转换成PhysicalPlan;

5.使用prepareForExecution()将PhysicalPlan转换成可执行物理计划;

6.使用execute()执行可执行物理计划;

7.生成SchemaRDD。

在整个运行过程中涉及到多个SparkSQL的组件,如SqlParse、analyzer、optimizer、SparkPlan等等

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。

 

转载于:https://www.cnblogs.com/itboys/p/9197201.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/570715.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Mysql的高可用方案及主从详细配置

1、常用的高可用MySQL解决方案: 数据库作为最基础的数据存储服务之一,在存储系统中有着非常重要的地位,因此要求其具备高可用性无可厚非。能实现不同SLA(服务水平协定)的解决方案有很多种,这些方案可以保证数据 库服务器在硬件或…

vue3+element plus组件库中el-carousel组件走马灯特效,当图片变动时下面数字也随着图片动态变化

1.效果图 2.html <section style"height:30%"><div class"left-img1-title"><img src"../assets/img/title.png"alt""srcset""><div class"text">回收垃圾数量</div></div>…

数据库MySQL/mariadb知识点——数据类型

数据类型 所谓的列类型&#xff0c;其实就是指数据类型&#xff0c;即对数据进行统一的分类&#xff0c;从系统的角度出发是为了能够使用统一的方式进行管理&#xff0c;更好的利用有限的空间。 在 SQL 中&#xff0c;将数据类型分成了三大类&#xff0c;分别为&#xff1a;数值…

期货大赛项目|九,fileinput插件的应用

引入JS和CSS bundles.Add(new ScriptBundle("~/bundles/fileinputJs").Include( "~/Content/vendors/bootstrap-fileinput-master/js/fileinput.min.js", "~/Content/vendors/bootstrap-fileinput-master/js/locales/zh.js", "~/Scripts/fi…

PLSQL中文显示乱码(问号)

1、输入 select * from V$NLS_PARAMETERS 查看第一行value值是否为简体中文 simplified chinese 实际显示为&#xff1a;AMERICAN 2、设置本地环境变量 &#xff1a;NLS_LANG NLS_LANGAMERICAN_AMERICA.ZHS16GBK NLS_LANG的值为三个划线值拼接而成。 3、重新打开PLSQL…

Mybatis下collections使用pageHelper进行分页

pageHelper在对mybatis一对多分页时造成查询总页数结果不对的情况。 可以做出如下修改&#xff1a; service层&#xff1a; public CommonResult worksList(String userId, int page, int pageSize) throws Exception { PageHelper.startPage(page, pageSize); List<…

解决ubuntu系统root用户下Chrome无法启动问题

说明&#xff1a;本文转载自-https://www.cnblogs.com/hbsygfz/p/8409517.html 由于ubuntu16.04系统自带的是Firefox浏览器&#xff0c;需要安装Chrome浏览器&#xff0c;但是在root用户下安装后发现&#xff0c;Chrome无法正常启动。安装及问题解决具体如下&#xff1a; 1. …

mysql ERROR 1045 和2058时(28000): 错误解决办法

mysql ERROR 1045 (28000): 错误解决办法 听语音|浏览&#xff1a;54286|更新&#xff1a;2018-02-23 14:34|标签&#xff1a;mysql 1234567分步阅读ERROR 1045 (28000): Access denied for user ODBClocalhost (using password: NO) ERROR 1045 (28000): Access denied for us…

maven POM总结

可继承的字段 version property 其他占坑&#xff1a; parent import scope Dependency_Management中的scope是可以被继承的&#xff0c;http://maven.apache.org/pom.html#Dependency_Management name 不可继承 artifactId 不可继承 &#xff0c; 确定打包的最终名称。 这个…

JVM从入门到放弃——JVM内存模型

前言 Java和C或者是C相比较而言&#xff0c;最大的区别是C系列的程序员在编写代码的时候&#xff0c;总是要对程序中的变量进行释放内存的操作&#xff0c;所以在编写C或者是C的程序员需要格外的谨慎&#xff0c;因为他们对程序的内存有着很高的权限&#xff0c;这样虽然是特点…

485. Max Consecutive Ones - LeetCode

Question 485. Max Consecutive Ones Solution 题目大意:给一个数组,取连续1的最大长度 思路:遍历数组,连续1就加1,取最大 Java实现: public int findMaxConsecutiveOnes(int[] nums) {if (nums null) return 0;int result 0;int tmp 0;for (int i : nums) {if (i 1) {tmp;…

MacBook创建docker私有仓库docker server gave HTTP response to HTTPS client 问题处理办法

在 mac上搭建一个私有仓库&#xff0c;在向仓库push镜像时&#xff0c;会报如下错误&#xff1a; #docker push 192.168.163.131:5000/test Get https://192.168.163.131:5000/v1/_ping: http: server gave HTTP response to HTTPS client 百度了下答案发现都不试用mac版本的d…

Redis基础1(定义及基础)

Redis 定义&#xff1a;Redis是一个软件&#xff0c;帮助开发者对一台机器的内存进行操作 安装redis软件方法&#xff1a; 超链接地址&#xff1a;https://www.cnblogs.com/L5251/articles/9146881.html Python中下载依赖包 pip3 install redis 测试Redis是否安装成功 # 1、引入…

vue-cli安装

、安装vue-cli 命令&#xff1a;npm install vue-cli -g -g表示全局安装 2、初始化项目 命令&#xff1a;vue init webpack my-project 使用vue命令初始化项目&#xff0c;并使用webpack打包 此时会跳出一系列问题&#xff0c;除了eslint那一项&#xff0c;其余的均可回答yes&a…

修复病毒破坏的文件关联并恢复程序图标

1.破坏文件关联的两种方式&#xff1a; &#xff08;1&#xff09;修改特定扩展名文件的对应名称。以.exe文件为例&#xff1a; 正常注册表中&#xff0c;.exe文件对应名称为&#xff1a; HKEY_CLASSES_ROOT\.exe &#xff08;默认&#xff09; exefile 病毒为…

双击程序后系统弹框“您无权访问此程序”的解决办法

xp下&#xff1a;我的电脑>工具>文件夹选项>查看&#xff0c;勾掉使用简单文件共享选项。如下图&#xff1a; 此时&#xff0c;在右键点击程序图标时&#xff0c;选项卡中会出现“安全”选项卡。如下图&#xff1a; 修改everyone为Administrator...并设置完全控制权限…

adb常用操作命令

1、adb devices 查看当前链接设备&#xff0c;列出连接到计算机的Android设备或者模拟器 2、adb install <apk文件路径> 安装软件 3、adb uninstall <软件名> 卸载apk之前要先查看报名&#xff1a; 知晓包名之后&#xff0c;就可以运用命令卸载该APK 4、adb shell …

轻量级ORM框架 【Dapper】 的使用

ORM是什么&#xff1f; 从字面理解&#xff0c;O是Object&#xff0c;对象&#xff1b;R是Relation&#xff0c;关系&#xff1b;M是Mapping&#xff0c;映射。所以&#xff0c;用一句话概括就是&#xff1a;ORM是一种对象关系映射的技术。 Dapper 是.NET下的一种ORM框架。 Dap…

系统提示一个程序正在被另一个程序调用,如何知道是被哪个程序调用

今天在处理一个病毒时&#xff0c;发现病毒文件无法复制。于是利用processxp找到了病毒文件是被哪个文件调用&#xff0c;然后用md关闭了调用句柄后成功复制文件。具体情况如下&#xff1a; 为了找到是哪个程序调用了befsvc.exe&#xff0c;打开processexplorer.exe&#xff0c…

通过修改explorer.exe内存隐藏文件及注册表项

记录今天分析的一个隐藏自身及注册表项的病毒。 1.概述&#xff1a; &#xff08;1&#xff09;此病毒文件为路径为&#xff1a;C:\Windows7\4D525EC1C14.exe&#xff0c;且注册了自启动项&#xff1a; HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run […