Spark SQL
支持通过DataFrame
接口对各种数据源进行操作。DataFrame
可以使用关系转换进行操作,也可以用于创建临时视图。将DataFrame
注册为临时视图允许您对其数据运行SQL
查询。
本实训介绍使用Spark
数据源加载和保存数据的一般方法,然后介绍可用于内置数据源的特定选项。
第1关:SparkSQL加载和保存:
DataFrameReader
用于从外部存储系统(例如文件系统,键值存储等)加载数据集的接口。使用SparkSession.read
来访问它。
DataFrameReader
提供了(json
,parquet
,jdbc
,orc
,libsvm
,csv
,text
)格式支持,DataFrameReader.load(String... paths)
方法支持多个路径的数据源,默认使用parquet
格式(除非另有配置,spark.sql.sources.default
)用于所有操作
Dataset<Row> usersDF = spark.read().load("examples/src/main/resources/users.parquet");
您还可以手动指定将要使用的数据源以及要传递给数据源的任何其他选项。数据源通过其全名指定(即org.apache.spark.sql.parquet
),但内置的来源,你也可以使用自己的短名称(json
,parquet
,jdbc
,orc
,libsvm
,csv
,text
)。从任何数据源类型加载的 Dataset 都可以使用此语法转换为其他类型。
要加载JSON
文件,您可以使用:
//加载
Dataset<Row> peopleDF =
spark.read().format("json").load("examples/src/main/resources/people.json");
要加载CSV
文件,您可以使用:
Dataset<Row> peopleDFCsv = spark.read().format("csv")
.option("sep", ";")
.option("inferSchema", "true")
.option("header", "true")
.load("examples/src/main/resources/people.csv");
直接在文件上运行SQL
您可以直接使用SQL
查询该文件,而不是使用读取API
将文件加载到 Dataset
并进行查询。
Dataset<Row> sqlDF =
spark.sql("SELECT * FROM parquet.`src/main/resources/users.parquet`");
保存到路径
DataFrameWriter
用于将数据集写入外部存储系统的接口(例如文件系统,键值存储等), 使用Dataset.write
访问它。
使用DataFrameWriter.save(String path)
,就可以将Dataset
的内容保存在指定的路径中。
//写入并保存到指定路径
peopleDF.select("name","age").write().format("parquet").save("F:\\test\\anamesAndAges");
保存模式介绍
save()
方法支持设置保存模式,使用DataFrameWriter.mode(SaveMode saveMode)
可用于指定将Dataset
保存到数据源的预期行为,指定如何处理现有数据(例如,执行时设置类型为Overwrite
,则数据将在写出新数据之前被删除。)但需要注意的这些保存模式不使用任何锁定并且不是原子的。
SaveMode
类型如下:
Scala/Java |
含义 |
---|---|
SaveMode.ErrorIfExists (默认) |
将Dataset 保存到数据源时,如果数据已存在,则会引发异常。 |
SaveMode.Append |
将Dataset 保存到数据源时,如果数据/表已存在,则Dataset的内容应附加到现有数据。 |
SaveMode.Overwrite |
覆盖模式意味着在将Dataset 保存到数据源时,如果数据/表已经存在,则预期现有数据将被Dataset 的内容覆盖。 |
SaveMode.Ignore |
忽略模式意味着在将Dataset 保存到数据源时,如果数据已存在,则预期保存操作不会保存Dataset 的内容而不会更改现有数据。这与CREATE TABLE IF NOT EXISTSSQL 中的类似。 |
//覆盖原有数据并写入到F:\\test\\anamesAndAges路径上
peopleDF.select("name","age").write().mode("overwrite").save("F:\\test\\anamesAndAges")
保存到持久表
Dataset
也可以使用saveAsTable
命令将持久表保存到Hive Metastore
中。请注意,使用此功能不需要现有的Hive
部署。Spark
将为您创建默认的本地Hive Metastore
(使用Derby
)。
与createOrReplaceTempView
命令不同,saveAsTable
将实现DataSet
的内容并创建指向Hive Metastore
中数据的指针。只要您保持与同一 Metastore
的连接,即使您的Spark
程序重新启动后,持久表仍然存在。可以通过spark.sql()
方法通过表的名称调用来创建持久表的Dataset
。
对于基于文件的数据源,例如text
,parquet
,json
等,您可以通过path
选项指定自定义表路径 ,例如:
df.write.option("path", "/some/path").saveAsTable("t")
删除表时,将不会删除自定义表路径,并且表数据仍然存在。如果未指定自定义表路径,则Spark
会将数据写入仓库目录下的默认表路径。删除表时,也将删除默认表路径。
从Spark 2.1
开始,持久数据源表将每个分区元数据存储在Hive Metastore
中。这带来了几个好处:
由于Metastore
只能返回查询所需