Spark SQL系列二

Data Sources

Spark SQL支持通过DataFrame接口操作多种类型的数据源。可以使用Relational transformation来操作DataFrame,也可以通过DataFrame来创建临时view。把一个DataFrame注册成临时view,这样就能使用SQL语句来操作数据。这个模块介绍了几种通用的方法,包括通过spark数据源来加载和保存数据,然后进入可用于内置数据源的特定选项。

Generic Load/Save Functions

最简单的格式,数据源可以用于所有操作。

val usersDF = spark.read.load("examples/src/main/resources/users.parquet")
usersDF.select("name", "favorite_color").write.save("namesAndFavColors.parquet")

Manually Specifying Options

你可以手动指定将要使用的数据源,以及传递给数据源的其他选项。数据源通过他们的全称来指定,内置数据源可以通过简称来指定。从任何数据源类型加载的DataFrame都可以使用此语法转换为其他类型。

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")

这些多出来的选项是针对写操作的。例如,你可以控制ORC数据源的布隆过滤器和字典编码,如下例子会基于favorite_color 创建一个布隆过滤器,为name和favorite_color进行字典编码。对于Parquet,也存在parquet.enable.dictionary,

usersDF.write.format("orc")
  .option("orc.bloom.filter.columns", "favorite_color")
  .option("orc.dictionary.key.threshold", "1.0")
  .save("users_with_options.orc")

Run SQL on files directly

你可以直接运行SQL语句,而不需要使用read相关的API把文件加载进DataFrame,然后再查询。

val sqlDF = spark.sql("SELECT * FROM parquet.`examples/src/main/resources/users.parquet`")

Save Modes

保存操作可以选择一个保存模式,它指定了怎么处理当前存在的数据。保存模式不会对数据进行锁定,并且不是原子操作。另外,如果保存操作指定的是Overwrite类型,那么在写新数据之前会先删除旧数据。


sparkle_sql.png

Saving to Persistent Tables

我们也可以使用saveAsTable 命令来把DataFrame保存到Hive metastore的持久表里,该功能并不一样需要部署Hive,Spark会为你创建一个本地 Hive metastore 。不像createOrReplaceTempView 命令,saveAsTable 命令将会实例化DataFrame的内容,还会创建一个指针指向metastore中的数据。即使你重启spark工程,持久表仍然会存在,只要你保持连接同一个metastore。通过调用SparkSession的table方法来创建持久表的DataFrame,此DataFrame与持久表同名。
对于文件类型的数据源,如text, parquet, json等等,你可以通过path选项来指定自定义表路径,如df.write.option("path", "/some/path").saveAsTable("t")。当把表删除时,表路径不会被移除,表的数据仍然存在。如果没有指定自定义表路径,spark会把数据写到默认表路径下,和warehouse同目录,此时如果把表删除,那表路径也会被删除。
从spark 2.1开始,持久化数据源表在Hive metastore中有单分区元数据,这么做有几个好处:
-由于metastore只会返回查询所需的分区,不需要在查找的时候访问所有的分区。
-可以通过Datasource API来使用Hive DDLs(例如:ALTER TABLE PARTITION ... SET LOCATION)
注意,在创建外部数据源表(具有path选项)的时候,默认情况不会收集分区信息。为了同步metastore中的分区信息,你可以调用 MSCK REPAIR TABLE。

Bucketing, Sorting and Partitioning

对于文件类型数据源,也可以对输出进行存储、排序或者分区。存储和排序仅适用于持久表。

peopleDF.write.bucketBy(42, "name").sortBy("age").saveAsTable("people_bucketed")

可以使用DataSet API的 save和saveAsTable方法来进行分区操作

usersDF.write.partitionBy("favorite_color").format("parquet").save("namesPartByColor.parquet")

对于单表,也可以同时使用分区和bucket操作

usersDF
  .write
  .partitionBy("favorite_color")
  .bucketBy(42, "name")
  .saveAsTable("users_partitioned_bucketed")

partitionBy方法按照Partition Discovery中的描述来创建目录结构。因此,它对具有高基数的列的适用性有限制。相比之下,BucketBy方法可以在固定数量的buckets分配数据,并且可以在许多唯一值无限制时使用。

你可能感兴趣的:(Spark SQL系列二)