版权声明:本文为博主原创(翻译)文章,未经博主允许不得转载。https://blog.csdn.net/jmx_bigdata/article/details/83619838
目录
一、 普通的Load/Save方式
其中最简单的一种方式是默认的数据源(parquet)
val usersDF = spark.read.load("examples/src/main/resources/users.parquet")
usersDF.select("name", "favorite_color").write.save("namesAndFavColors.parquet")
1. 手动指定文件格式
可以手动指定数据源的格式,对于内置的数据源而言,可以不使用全限定名(org.apache.spark.sql.parquet
)),直接使用短名称(json
, parquet
, jdbc
, orc
, libsvm
, csv
, text
)).
加载JSON格式文件:
val peopleDF = spark.read.format("json").load("examples/src/main/resources/people.json")
peopleDF.select("name", "age").write.format("parquet").save("namesAndAges.parquet")
加载CSV格式文件:
val peopleDFCsv = spark.read.format("csv")
.option("sep", ";")
.option("inferSchema", "true")
.option("header", "true")
.load("examples/src/main/resources/people.csv")
2.使用SQL直接查询文件
val sqlDF = spark.sql("SELECT * FROM parquet.`examples/src/main/resources/users.parquet`")
3.保存模式
保存操作可以选择使用saveMode的参数,该saveMode主要是指定在保存数据存在的情况下,以什么方式处理保存的数据。
val df = spark.read.json("file:///e:/employees.json")
df.write.format("json").mode(SaveMode.Append).save("e:/employees")
4.保存为永久的表
使用 saveAsTable
可以将DataFrame持久化为Hive中的表,对于基于文件的数据源( text, parquet, json等),在保存的时候可以指定一个具体的路径,比如 df.write.option("path", "/some/path").saveAsTable("t")(存储在指定路径下的文件格式为parquet)。
当表被删除时,自定义的表的路径和表数据不会被移除。如果没有指定具体的路径,spark默认的是warehouse的目录(/user/hive/warehouse),当表被删除时,默认的表路径也会被删除。
从Spark 2.1开始,持久化数据源表会将每个分区元数据存储在Hive Metastore中。这带来了几个好处
(1)由于Metastore只返回查询所需要的分区,因此不再需要扫描所有分区。
(2)Hive 的DDL操作(比如 ALTER TABLE PARTITION ... SET LOCATION)可被用于使用Datasource API创建表。
请注意,在创建外部数据源表(带有path选项的表)时,默认情况下不会收集分区信息。要同步Metastore中的分区信息,可以调用MSCK REPAIR TABLE 表名 ,比如MSCK REPAIR TABLE people。
val df = spark.read.json("spark_data/people.json")
df.write.option("path","/user/root/spark_data/people").saveAsTable("people")
5. 分桶、排序与分区
对于基于文件类型的数据源( text, parquet, json等) ,可以将保存的结果进行分桶、排序和分区。分桶和排序仅仅适用于输出为持久化表的情况 。
peopleDF.write.bucketBy(42, "name").sortBy("age").saveAsTable("people_bucketed")
当使用DataSet的API时,对于save和saveAsTable而言,都可以使用分区 ,下面的第一条代码会在HDFS上的当前用户路径下产生一个文件夹namesPartByColor.parquet,里面包含了两个分区文件夹。第二条代码会在/user/hive/warehouse/namespartbycolor产生一个分区表。(下面两幅图为hue中的截图)
usersDF.write.partitionBy("favorite_color").format("parquet").save("namesPartByColor.parquet")
userDF.write.partitionBy("favorite_color").format("parquet").saveAsTable("namesPartByColor")
对于单独的一个表,可以同时使用分区和分桶
usersDF
.write
.partitionBy("favorite_color")
.bucketBy(42, "name")
.saveAsTable("users_partitioned_bucketed")
二、Parquet文件
parquet是一种列存储格式的文件,支持许多的数据处理系统。Spark SQL 支持Parquet文件的读和写,当读取Parquet格式文件时,会自动保留原始文件的schema,当向Parquet文件写数据时,考虑到兼容性的原因,所有的列会自动被转为可以为null的类型。
1.编程的方式加载数据
val peopleDF = spark.r