文章目录
28 sparkSQL
1.sparkSQL的概述
什么是Spark SQL
结构化:mysql当中的表,字段个数一定,字段的类型也一定了
半结构化:类似于xml或者json
非结构化:类似于音频或者视频
sparkCore ==> RDD数据抽象 ==> sparkContext 操作数据对象
sparkSQL ==> dataFrame/dataSet数据抽象 ==> SparkSession操作数据对象
sparkSQL特点:
1.易整合
2.统一的数据访问
3.兼容hive:sparkSQL可以无缝的直接使用hql语句来做数据分析。可以使用spark on hive,将hive底层的执行引擎直接给换成spark的执行引擎
4.标准的数据连接
2.RDD以及df以及ds
dataset是最晚出来的一个数据抽象,dataset的出现主要是为了提供同一个数据抽象访问
dataset可能在未来的版本里面统一rdd以及dataframe,替换掉rdd以及df,只剩下ds
rdd以及df以及dataset都是弹性分布式数据集
df提供schema的定义。scheam定义了df当中数据的字段的个数,以及字段的类型。schema相当于定义了表的规范,然后就可以将df当中的数据映射成为一张表,通过sql语句的方式去操作它
dataframe也是懒执行的
dataframe摆脱了jvm堆内存的限制,避免了频繁的GC。dataFrame可以将数据保存到物理内存里面去
dataframe缺少编译器的类型安全的检查,使用的是运行期的检查 int c = 1/0
dataset是dataframe的扩展
dataset使用的是编译期类型检查 int a = "hello"。编译期的检查更加安全一点,代码没有可能打包到集群上面去运行
rdd以及dataframe以及dataset三者之间可以相互的进行转化
三者的共性
三者的区别
3.dataframe的创建以及操作
3.1 读取文本文件创建DataFrame
第一种方式:通过RDD配合case class 样例类来将文本文件的数转换 成为DF
1.读取文本文件成为一个rdd => 2.将rdd给切开,然后将数据转换成为RDD[CASE Class] => 3.将RDD[case class] 转换成为DF
第一步:创建文本文件
在linux的/export/servers/路径下创建文本文件
cd /export/servers/
vim person.txt
1 zhangsan 20
2 lisi 29
3 wangwu 25
4 zhaoliu 30
5 tianqi 35
6 kobe 40
第二步:定义RDD
使用spark-shell 进入spark客户端
cd /export/servers/spark-2.2.0-bin-2.6.0-cdh5.14.0/
bin/spark-shell --master local[2]
val lineRDD = sc.textFile("file:///export/servers/person.txt").map(x => x.split(" "))
第三步:定义case class样例类
case class Person(id:Int,name:String,age:Int)
第四步:关联RDD与case class
val personRDD = lineRDD.map(x => Person(x(0).toInt,x(1),x(2).toInt))
第五步:将RDD转换成DF
val personDF = personRDD.toDF
注意:DF也可以转换成为RDD,直接使用DF调用rdd方法即可
scala> personDF.rdd.collect
res38: Array[org.apache.spark.sql.Row] = Array([1,zhangsan,20], [2,lisi,29], [3,wangwu,25], [4,zhaoliu,30], [5,tianqi,35], [6,kobe,40])
第二种方式:通过sparkSession构建DataFrame
val personDF2 = spark.read.text("file:///export/servers/person.txt")
3.2 读取json文件创建DataFrame
spark给我们提供了json格式的示例文件,路径在
/export/servers/spark-2.2.0-bin-2.6.0-cdh5.14.0/examples/src/main/resources/people.json
我们可以直接通过spark解析json数据进行创建DF
val jsonDF = spark.read.json("file:///export/servers/spark-2.2.0-bin-2.6.0-cdh5.14.0/examples/src/main/resources/people.json")
3.3 读取parquet列式存储格式文件创建DataFrame
spark也给我们提供了parquet格式的数据,我们也可以通过spark直接解析parquet格式的数据来进行创建DF,示例文件的路径在
/export/servers/spark-2.2.0-bin-2.6.0-cdh5.14.0/examples/src/main/resources/users.parquet
val parquetDF = spark.read.parquet("file:///export/servers/spark-2.2.0-bin-2.6.0-cdh5.14.0/examples/src/main/resources/users.parquet")
parquetDF.show
parquetDF.printSchema 打印DataFrame的Schema信息
3.4 DF的语法操作风格
DSL语法操作风格:
查看某一个字段四种语法
scala> personDF.select("name").show
personDF.select($"name").show
personDF.select(col("name")).show
personDF.select(personDF.col("name")).show
将年龄值加1
personDF.select($"name",$"age",$"age" + 1).show
过滤age大于等于25
personDF.filter($"age" > 25).show
统计年龄大于30岁一共多少人
personDF.fi
lter(col("age")>30).count()
按照年龄进行分区,统计每组有多少人
personDF.groupBy($"age").count.show
SQL语法操作风格:
直接使用sql语句来实现数据的分析
1.将DataFrame注册成表
scala> personDF.registerTempTable("t_person")
warning: there was one deprecation warning; re-run with -deprecation for details
2.查询年龄最大的前两名
scala> spark.sql("select * from t_person order by age desc limit 2 ").show
3.显示表的Schema信息
scala> spark.sql("desc t_person").show
4.查询年龄大于30的人的信息
scala> spark.sql("select * from t_person where age > 30").show
4.dataset介绍
4.1 创建DataSet
创建dataSet一共可以有四种方式
1.从集合当中创建
scala> val ds1 = spark.createDataset(1 to 10)
2.从已经存在的rdd当中进行创建
val personRDD = sc.textFile("file:///export/servers/person.txt")
val ds2 =spark.createDataset(personRDD)
3.通过样例类配合集合创建ds
case class Person(name:String,age:Int)
val personDataList = List(Person("zhangsan",18),Person("lisi",28))
val personDS = personDataList.toDS
4.使用df转化生成ds
case class Person(name:String,age:Long)
val jsonDF = spark.read.json("file:///export/servers/spark-2.2.0-bin-2.6.0-cdh5.14.0/examples/src/main/resources/people.json")
val jsonDS = jsonDF.as[Person]
4.2 DataFrame与DataSet互相转换
5.编程方式实现sparkSQL查询
5.1 编写Spark SQL程序实现RDD转换成DataFrame
第一步:创建maven工程并导入依赖jar包
<properties>
<scala.version>2.11.8</scala.version>
<spark.version>2.2.0</spark.version>
</properties>
<dependencies>
<dependency>
<groupId>org.scala-lang</groupId>
<artifactId>scala-library</artifactId>
<version>${
scala.version}</version>
</dependency>
<dependency>
<groupId>org.apache.spark</groupId>
<artifactId>spark-core_2.11</artifactId>
<version>${
spark.version}</version>
</dependency>
<dependency>
<groupId>org.apache.spark</groupId>
<artifactId>spark-sql_2.11</artifactId>
<version>${
spark.version}</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-client</artifactId>
<version>2.7.5</version>
</dependency>
</dependencies>
<build>
<sourceDirectory>src/main/scala</sourceDirectory>
<testSourceDirectory>src/test/scala</testSourceDirectory>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
<!-- <verbal>true</verbal>-->
</configuration>
</plugin>
<plugin>
<groupId>net.alchim31.maven</groupId>
<artifactId>scala-maven-plugin</artifactId>
<version>3.2.0</version>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>testCompile</goal>
</goals>
<configuration>
<args>
<arg>-dependencyfile</arg>
<arg>${
project.build.directory}/.scala_dependencies</arg>
</args>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.1.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
<transformers>
&