一、Spark.Sql简介
Spark.sql是Spark四大组件之一,是Spark数据处理中用的最多的组件。SparkSQL在SparkCore的基础上对外提供了SQL接口,可以让熟悉SQL的技术人员快速上手。其编程入口为SparkSession。
.SparkSQL所有的内容位于pyspark.sql这个模块下,包含了SparkSession、Column、Row等众多的核心内容。SparkSQL是面向结构化数据的利刃,处理表格如常规的关系型数据库一样,不管是提供的丰富的API还是执行的效率上,都有很大的优势。
不过对于非结构化的数据,还得借助RDD来进行基本的处理。
DataFrame是SparkSQL的利器,它是一个类似于Pandas中的DataFrame的表格对象,当然其底层是基于了RDD的,最终的计算还是需要转换成RDD来进行STAGE划分的阶段的。它在RDD的基础上提供了表格如column、Row、索引等信息,已经有结构化的数据信息,因此使用基于DataFrameAPI编写的Spark程序在性能上肯定要优于基于RDD编写出来的程序。另外一个优势是他可以使的只会SQL的程序员可以非常容易上手使用。
之前SparkSQL这个模块是基于HIVE的SQL解析器的,因为不好优化,随时SPARK的发展,Spark团队重新开发了Spark特有的SQL解析器,使得SparkSQL在性能与灵活性更进一步,当然SparkSession中builder上有一个方法可以设置启用对HIVE查询的支持,从而使得SPARK可以方便的查询HIVE数据库中的数据
按官方说法SparkSql底层使用了Catalyst优化器对SQL语句进行优化,Tungsten对CPU和Memory的优化,从而使得SparkSQL的执行速度进一步提升。
二、技术细节
1、编程入口
要编写SparkSQL程序必须通过SparkSession对象,这个类中有个builder方法,可以实例化一个SparkSession对象
from pyspark.sql import SparkSession
spark = SparkSession.builder.master("spark://hadoop-maste:7077").appName("test").config("spark.xxxx.conf", "some-value")
.getOrCreate()
master用于指定spark集群地址、appName用于设置app的名称;config中以key,value的形式进行一些配置config可以以链式编程的方式多次调用,每次调用可设置一组key,value配置。
而且conf中还可以传入一个关键字参数conf,指定外部的SparkConf配置对象getOrCreate,若存在sparksession实例直接返回,否则实例化一个sparksession返回
enableHiveSupport()启用对hive的支持,pyspark.sql. HiveContext (sparkContext, jhiveContext=None),用于整合Hive
数据仓库的,读取Hive表格需要借助HiveContext。
这些配置可以通过SparkSession上的conf属性来获取,这个conf实际上就是RuntimeConfig对象,通过conf上的get方法获取对应的配置和通过spark.sparkContext.getConf().get获取配置是类似的
2、创建DataFrame
createDataFrame (data, schema=None, samplingRatio=None, verifySchema=True)这个方法。可以使用RDD或则python list获取pandas.DataFrame来创建。当schema被指定的时候,每个列的类型将会通过列来进行推断。samplingRatio指定用于类型推断的样本的比例,verifySchema验证每行的数据类型是否符合schema的定义。
从上面的创建方法可以知道 ,创建一个DataFrame必须要一个data也就是value值,这里的data也是可以是外部数据,还有一个就是schema信息表示列信息与类型,所以只要我们指定了相关value与schema就可以创建。
举例:使用list-tuple来创建
I = [('TOM',11),('LIYUE',12)]
spark.createDataFrame(I,schema=['name','age']).collect()
像上述例子,如何你不指定schema信息,系统会自动推断,会给自动加默认的schema信息。
通过RDD构建Row对象也是可以直接创建的:
from spark.sql import Row
user = Row('name','age')
a = [('Tom',11),('liyue',12)]
rdd = sc.parallelize(a,3)
user = rdd.map(lambda x: Row(*x))
df = spark.createDataFrame(user)
df.collect()
其他创建方法如:range方法创建列标签返回df、read方法读取外部数据源创建DataFrame,readstream方法读取stream流数据来创建等
3、如何查询DataFrame的数据
我们可以操作类似PANDAS的dataframe方式操作sparksql的dataframe的,但sparksql有个就去sql可以使用我们就像查询关系型数据库那样使用SQL语句来查询,可以使用show来显示
有时候我们查询的结果希望按照自己的方式,自定义 一个函数,UDF,pyspark也是支持UDF的,但总是另人诟病效率低下。
4、重要方法与对象
其实 dataframe作为RDD上的高级对象,很多RDD有的个方法他也是有的,有些他没有方法也可以通过转换成RDD来使用。
重要的方法有:createOrReplaceTempView创建一个本地的临时视图、cache、coalesce重分区等。。。。。
重要的对象:
GroupeData 对象,它是由方法groupBy()方法创建的,提供了DataFrame上用于数据聚合的系列方法。如agg(),apply(),avg(),count(),max(),min(),sum()等。。。。
Column对象:它代表的DataFrame的列的信息,提供了一些对列操作的方法
ROW对象:它代表了DataFrame的行
Catalog对象:此对象包含了SPARKSQL中的表与数据仓库状态的方法,如:iscached(),cachetalbe(),删除临时表droptempview、设置数据库等。。。。。。。。。。。
三、其他专项探索
1、在数据处理空值的处理很普通,SPAKRSQL是如何处理的
有一个对象:DataFrameNaFunctions,它就是处理NA数据的,如何使用?只要dataframe.na就可以引用它了。
2、统计模块
DataframeStatFunctions提供了很多DATAFRAME用于统计 的方法,通过dataframe.stat来引用
3、DataFrameReader与DataFrameWriter
我们在dataframe.read去读取数据时其实就是引用DataFrameReader来读取的,DataFrameReader是dataframe用于读取外部数据 的接口,有read就write,所以写数据就用DataFrameWriter
4、数据类型
dataframe有哪些数据类型?都在spark.sql.types模块中,可以dir一下看看
5、函数模块
sparksql提供了一个functions模块spark.sql.functions,里面实现了很多有用的方法,可以直接拿来用就行。
6、性能调优
先MARK一下,以后再来说