SparkSQL-数据源

Spark SQL的DataFrame接口支持多种数据源的操作。一个DataFrame可以进行RDDs方式的操作,也可以被注册为临时表。把DataFrame注册为临时表之后,就可以对该DataFrame执行SQL查询。Data Sources这部分首先描述了对Spark的数据源执行加载和保存的常用方法,然后对内置数据源进行深入介绍。

一、一般Load/Save方法

Spark SQL的默认数据源为Parquet格式。数据源为Parquet文件时,Spark SQL可以方便的执行所有的操作。修改配置项spark.sql.sources.default,可修改默认数据源格式。读取Parquet文件示例如下:

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

二、手动指定选项

当数据源格式不是parquet格式文件时,需要手动指定数据源的格式。数据源格式需要指定全名(例如:org.apache.spark.sql.parquet),如果数据源格式为内置格式,则只需要指定简称(jsonparquetjdbcorclibsvmcsvtext)。通过指定的数据源格式名,可以对DataFrames进行类型转换操作。示例如下:

  • 加载JSON文件
Dataset peopleDF =
  spark.read().format("json").load("examples/src/main/resources/people.json");
peopleDF.select("name", "age").write().format("parquet").save("namesAndAges.parquet");
  • 加载CSV文件
Dataset peopleDFCsv = spark.read().format("csv")
  .option("sep", ";")
  .option("inferSchema", "true")
  .option("header", "true")
  .load("examples/src/main/resources/people.csv");

三、直接在文件上运行SQL

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

四、存储模式

可以采用SaveMode执行存储操作,SaveMode定义了对数据的处理模式。需要注意的是,这些保存模式不使用任何锁定,不是原子操作。此外,当使用Overwrite方式执行时,在输出新数据之前原数据就已经被删除。SaveMode详细介绍如下表:

Dataset peopleDF = spark.read().format("json")
				.load("hdfs://spark1:9000/people.json"); 
peopleDF.save("hdfs://spark1:9000/people_savemode_test", "json", SaveMode.Append);

SparkSQL-数据源_第1张图片

SparkSQL-数据源_第2张图片 五、持久化到表

DataFrames 也可以使用 saveAsTable 命令作为 persistent tables (持久表)保存到 Hive metastore 中. 请注意, existing Hive deployment (现有的 Hive 部署)不需要使用此功能. Spark 将为您创建默认的 local Hive metastore (本地 Hive metastore)(使用 Derby ). 与 createOrReplaceTempView 命令不同, saveAsTable 将 materialize (实现) DataFrame 的内容, 并创建一个指向 Hive metastore 中数据的指针. 即使您的 Spark 程序重新启动, Persistent tables (持久性表)仍然存在, 因为您保持与同一个 metastore 的连接. 可以通过使用表的名称在 SparkSession上调用 table 方法来创建 persistent tabl (持久表)的 DataFrame .

对于 file-based (基于文件)的 data source (数据源),例如 text, parquet, json等,您可以通过 path 选项指定 custom table path (自定义表路径), 例如 df.write.option("path", "/some/path").saveAsTable("t") . 当表被 dropped (删除)时, custom table path (自定义表路径)将不会被删除,并且表数据仍然存在。如果未指定自定义表路径,Spark 将把数据写入 warehouse directory (仓库目录)下的默认表路径。当表被删除时, 默认的表路径也将被删除。

从 Spark 2.1 开始, persistent datasource tables (持久性数据源表)将 per-partition metadata (每个分区元数据)存储在 Hive metastore 中. 这带来了几个好处:

  • 由于 metastore 只能返回查询的必要 partitions (分区), 因此不再需要将第一个查询上的所有 partitions discovering 到表中。
  • Hive DDLs 如 ALTER TABLE PARTITION ... SET LOCATION 现在可用于使用 Datasource API 创建的表。

请注意,创建 external datasource tables (外部数据源表)(带有 path 选项)的表时,默认情况下不会收集 partition information (分区信息)。要 sync (同步) metastore 中的分区信息, 可以调用 MSCK REPAIR TABLE。

六、分桶,排序和分区

对于 file-based data source (基于文件的数据源), 也可以对 output (输出)进行 bucket 和 sort 或者 partition . Bucketing 和 sorting 仅适用于 persistent tables :

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

在使用 Dataset API 时, partitioning 可以同时与 save 和 saveAsTable 一起使用。

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

可以为 single table (单个表)使用 partitioning 和 bucketing:

peopleDF
  .write()
  .partitionBy("favorite_color")
  .bucketBy(42, "name")
  .saveAsTable("people_partitioned_bucketed");

partitionBy 创建一个 directory structure (目录结构), 如Partition Discovery部分所述. 因此, 对 cardinality (基数)较高的 columns 的适用性有限. 相反, bucketBy 可以在固定数量的 buckets 中分配数据, 并且可以在 a number of unique values is unbounded (多个唯一值无界时)使用数据。

你可能感兴趣的:(大数据/Spark/Spark,SQL)