1.数据读取框架DataFrameReder
(1)使用场景
- SparkSQL中专门有一个框架用于读取外部数据源,叫做DataFrameReder
(2)构成
1.schema
- 结构信息
2.option
- 读取时的参数
3.format
- 数据源类型
(3)示例
import org.apache.spark.sql.{DataFrame, SparkSession}
import org.junit.Test
class sparkSQLDemo {
@Test
def reader1(): Unit = {
//1.创建sparkSession
val spark = SparkSession.builder()
.master("local[6]")
.appName("dataset2")
.getOrCreate()//创建对象
//2.有两种读取数据源形式
//2.1 load方式读取csv文件
spark.read
.format("csv")
.option("header",value = true)
.option("inferScheme",value = true)//自动进行数据结构推断
.load("dataset/BeijingPM20100101_20151231.csv")
.show()
//2.2对上面方式的简写
spark.read
.option("header",value = true)
.option("inferScheme",value = true)//自动进行数据结构推断
.csv("dataset/BeijingPM20100101_20151231.csv")
.show()
}
}
2.数据写入框架DataFrameWriter
(1)使用场景
- sparkSQL专门为写入数据而创建的框架DataFrameWriter
(2)构成
1.source
- 写入目标,文件格式等,通过format设定
2.mode
- 设置写入模式,是覆盖表还是向表中追加,通过mode(SaveMode.xxx)设定
2.1error
- 将df保存到source时,如果目标已经存在,则报错
2.2append
- 将df保存到source时,如果目标已经存在,则添加文件中
2.3overwrite
- 将df保存到source时,如果目标已经存在,则使用df中数据完全覆盖目标
2.4ignore
- df保存到source时,如果目标已经存在,则不会保存df数据
3.extraOptions
- 外部参数,通过option设定
4.partitiongColumns
- 分区,通过partitionBy设定
5.bucketColumnNames
- 分桶,通过bucketBy设定
6.sortColumnNamaes
- 用于排序的列,通过sortBy设定
(3)示例
import org.apache.spark.sql.SparkSession
import org.junit.Test
class sparkSQLDemo {
@Test
def writer1(): Unit = {
//1.创建sparkSession
val spark = SparkSession.builder()
.master("local[6]")
.appName("dataset2")
.getOrCreate()//创建对象
//2.读取数据集
val df = spark.read
.option("head", value = true)
.csv("dataset/BeijingPM20100101_20151231.csv")
//3.两种写入方式
//3.1
df.write.json("dataset/beijing_pm.json")
//3.2
df.write.format("json").save("dataset/北京_pm_2222.json")
}
}
3.读写Parquet数据格式
- Parqute数据格式是为了保存比较复杂数据,并且保证性能和压缩率而产生的文件存储格式
(1)Parquet文件格式使用场景
- 数据抽取的时候,存放到hdfs中的时候可能会用到Parquet格式
- spark在处理的过程中,也有可能使用Parquet进行暂存
(2)操作Parquet示例
import org.apache.spark.sql.SparkSession
import org.junit.Test
class sparkSQLDemo {
@Test
def parquet1(): Unit = {
//1.创建sparkSession
val spark = SparkSession.builder()
.master("local[6]")
.appName("dataset2")
.getOrCreate()//创建对象
//2.读取数据集
val df = spark.read
.option("head", value = true)
.csv("dataset/BeijingPM20100101_20151231.csv")
//3.把数据写为Parquet格式
df.write.format("parquet").save("dataset/北京_pm_3")
//4.读取Parquet格式文件
spark.read
.format("parquet")
.load("dataset/北京_pm_3")
.show()
}
}
4.spark读写分区(与Hive分区一致)
(1)分区概念
分区表可以按照某一列作为分区列,将数据放入不同的文件中,
因为Hive很重要,spark要经常和hive进行配合,所有spark在设计之初就就规定了要支持分区这种文件夹的读取
(2)写文件的时候如何分区
import org.apache.spark.sql.SparkSession
import org.junit.Test
class sparkSQLDemo {
@Test
def Partition(): Unit = {
//1.创建sparkSession
val spark = SparkSession.builder()
.master("local[2]")
.appName("dataset3")
.getOrCreate()//创建对象
//2.读取数据集
val df = spark.read
.option("header", value = true)
.csv("dataset/BeijingPM20100101_20151231.csv")
//3.写文件,表分区
df.write
.partitionBy("year","month")
.save("dataset/北京_pm_4")
}
}
- 先按照年进行分区,在按照月进行分区
(3)如何读分区文件
import org.apache.spark.sql.SparkSession
import org.junit.Test
class sparkSQLDemo {
@Test
def Partition(): Unit = {
//1.创建sparkSession
val spark = SparkSession.builder()
.master("local[2]")
.appName("dataset3")
.getOrCreate()//创建对象
//2.读文件,自动发现分区
//
spark.read
.parquet("dataset/beijing_pm4/")
.printSchema()
}
}
- spark读取分区文件时会自动分区发现
5.saprkSQL读取JSON
import org.apache.spark.sql.SparkSession
import org.junit.Test
class sparkSQLDemo {
@Test
def Json(): Unit = {
//1.创建sparkSession
val spark = SparkSession.builder()
.master("local[2]")
.appName("dataset3")
.getOrCreate()//创建对象
//读数据
val df = spark.read
.option("header", value = true)
.csv("dataset/BeijingPM20100101_20151231.csv")
//写一个json数据文件
df.write
.json("dataset/北京pm5.json")
//读取json文件
spark.read
.json("dataset/北京pm5.json")
.show()
}
}
5.1Json格式小技巧
(1)toJSON
1.使用场景
toJSON可以将df数据结构转换为Json格式
数据处理完了以后,df如果是一个对象,如果其他系统只支持JSON格式数据sparkSQL如果和这种系统进行整合时候,就需要进行数据类型转换
把DataSet[Object]转为DataSet[JsonString]
2.示例
package it.yuge.sql
import org.apache.spark.sql.SparkSession
import org.junit.Test
class sparkSQLDemo {
@Test
def Json1(): Unit = {
//1.创建sparkSession
val spark = SparkSession.builder()
.master("local[2]")
.appName("dataset3")
.getOrCreate()//创建对象
//读数据
val df = spark.read
.option("header", value = true)
.csv("dataset/BeijingPM20100101_20151231.csv")
/**
* 使用toJSON的场景:
* 数据处理完了以后,df如果是一个对象,如果其他系统只支持JSON格式数据
* sparkSQL如果和这种系统进行整合时候,就需要进行转换
*/
df.toJSON.show()
}
}
(2)可以直接从RDD直接读取Json的df
1.使用场景
从消息队列中取出JSON格式数据,需要使用sparkSQL进行处理
把RDD[JsonString]转为Dataset[Object]
2.示例
import org.apache.spark.sql.SparkSession
import org.junit.Test
class sparkSQLDemo {
@Test
def Json1(): Unit = {
//1.创建sparkSession
val spark = SparkSession.builder()
.master("local[2]")
.appName("dataset3")
.getOrCreate()//创建对象
//读数据
val df = spark.read
.option("header", value = true)
.csv("dataset/BeijingPM20100101_20151231.csv")
val jsonrdd = df.toJSON.rdd
spark.read.json(jsonrdd).show()
}
}
6.sparkSQL整合Hive
Hive 中主要的组件就三个, HiveServer2 负责接受外部系统的查询请求, 例如 JDBC, HiveServer2 接收到查询请求后, 交给 Driver 处理, Driver 会首先去询问 MetaStore 表在哪存, 后 Driver 程序通过 MR 程序来访问 HDFS 从而获取结果返回给查询请求者
而 Hive 的 MetaStore 对 SparkSQL 的意义非常重大, 如果 SparkSQL 可以直接访问 Hive 的 MetaStore, 则理论上可以做到和 Hive 一样的事情, 例如通过 Hive 表查询数据
(1)开启 Hive 的 MetaStore 独立进程
1.修改 hive-site.xml
使用Notepad++连接node02节点对hive配置文件就行修改
2.启动 Hive MetaStore
nohup /export/servers/hive/bin/hive --service metastore 2>&1 >> /var/log.log &
jps看到RunJar运行说明hive启动成功
nohub :放在命令开头,表示不挂起,关闭终端后,仍然运行。
&:放在命令结尾,表示后台运行,不占用终端显示。
2>&1 >>/var/log.log 将–service metastore运行时的2>&1 意思是窗口不输出内容输出到/var/log.log日志文件下
(2) SparkSQL 整合Hive 的 MetaStore
SparkSQL 整合 Hive 的 MetaStore 主要思路就是要通过配置能够访问它, 并且能够使用 HDFS 保存 WareHouse, 这些配置信息一般存在于 Hadoop 和 HDFS 的配置文件中, 所以可以直接拷贝 Hadoop 和 Hive 的配置文件到 Spark 的配置目录
cd /export/servers/hive/conf
cp hive-site.xml /export/servers/spark/conf/ //hive的site配置文件拷贝到spark的conf目录下
cd /export/servers/hadoop/etc/hadoop
cp core-site.xml hdfs-site.xml /export/servers/spark/conf/ //和hdfs的配置文件拷贝到spark的conf目录下
scp -r /export/servers/spark/conf node01:/export/servers/spark/conf
scp -r /export/servers/spark/conf node03:/export/servers/spark/conf
(3)使用 SparkSQL 处理数据并保存进 Hive 表
1.导入 Maven 依赖
<dependency>
<groupId>org.apache.spark</groupId>
<artifactId>spark-hive_2.11</artifactId>
<version>${spark.version}</version>
</dependency>
2. SparkSQL 处理数据并保存进 Hive 表
如果希望使用 SparkSQL 访问 Hive 的话, 需要做两件事
- 开启 SparkSession 的 Hive 支持,经过这一步配置, SparkSQL 才会把 SQL 语句当作 HiveSQL 来进行解析
- 设置 WareHouse 的位置虽然 hive-stie.xml 中已经配置了 WareHouse 的位置, 但是在 Spark 2.0.0 后已经废弃了 hive-site.xml 中设置的 hive.metastore.warehouse.dir, 需要在 SparkSession 中设置 WareHouse 的位置
在这里插入代码片
7.sparkSQL读取JDBC
略