spark SQL Parquet 文件的读取与加载

是由许多其他数据处理系统支持的柱状格式。Spark
SQL支持阅读和编写自动保留原始数据模式的Parquet文件。在编写Parquet文件时,出于兼容性原因,所有列都会自动转换为空。

1, 以编程方式加载数据

这里使用上一节的例子中的数据:常规数据加载

  private def runBasicParquetExample(spark: SparkSession): Unit = {
     import spark.implicits._
    //
    val peopleDF = spark.read.json("examples/src/main/resources/people.json")
    //DataFrames可以保存为Parquet文件,维护模式信息
    peopleDF.write.parquet("people.parquet")     //在上面创建的parquet文件中读取
    // Parquet文件是自描述的,所以模式被保存
    //加载Parquet文件的结果也是一个DataFrame 
    val parquetFileDF = spark.read.parquet("people.parquet")     // Parquet文件也可以用来创建临时视图,然后在SQL语句
     parquetFileDF.createOrReplaceTempView("parquetFile")
    val namesDF = spark.sql("SELECT name FROM parquetFile WHERE age BETWEEN 13 AND 19")
    namesDF.map(attributes => "Name: " + attributes(0)).show()
    // +------------+
    // |       value|
    // +------------+
    // |Name: Justin|
    // +------------+
  }

2,分区操作

表分区是像Hive这样的系统中常用的优化方法。在分区表中,数据通常存储在不同的目录中,分区列值在每个分区目录的路径中编码。现在,Parquet数据源能够自动发现和推断分区信息。例如,我们可以使用以下目录结构,两个额外的列gender和country分区列将所有以前使用的人口数据存储到分区表中:

path
└── to
└── table
├── gender=male
│ ├── ...
│ │
│ ├── country=US
│ │ └── data.parquet
│ ├── country=CN
│ │ └── data.parquet
│ └── ...
└── gender=female
├── ...

├── country=US
│ └── data.parquet
├── country=CN
│ └── data.parquet
└── ...

通过传递path/to/table给SparkSession.read.parquet或者SparkSession.read.load,Spark SQL将自动从路径中提取分区信息。现在,返回的DataFrame的模式变成:

root
|-- name: string (nullable = true)
|-- age: long (nullable = true)
|-- gender: string (nullable = true)
|-- country: string (nullable = true)

请注意,分区列的数据类型是自动推断的。目前支持数字数据类型和字符串类型。有时用户可能不希望自动推断分区列的数据类型。对于这些用例,可以使用spark.sql.sources.partitionColumnTypeInference.enabled默认 的自动类型推断来配置true。当禁用类型推断时,字符串类型将用于分区列。

      从Spark 1.6.0开始,默认情况下,分区仅在给定路径下找到分区。对于上面的例子,如果用户传递path/to/table/gender=male给 SparkSession.read.parquet或者SparkSession.read.load,gender将不会被视为分区列。如果用户需要指定启动分区发现的基本路径,则可以basePath在数据源选项中进行设置。例如,何时path/to/table/gender=male将数据的路径和用户设置basePath为path/to/table/,gender将成为分区列。

3, scheme 合并

像ProtocolBuffer,Avro和Thrift一样,Parquet也支持模式演变。用户可以从简单的模式开始,并根据需要逐渐向模式添加更多的列。通过这种方式,用户可能会以不同的但是 相互兼容的模式结束多个Parquet文件。Parquet数据源现在可以自动检测这种情况并合并所有这些文件的模式。

     由于模式合并是一个相对昂贵的操作,并且在大多数情况下不是必需的,所以我们从1.5.0开始默认关闭它。你可以通过

1)  将数据源选项设置mergeSchema为true读取Parquet文件(如下面的示例所示)

2)设置全局SQL选项spark.sql.parquet.mergeSchema来true。

例子如下:

  private def runParquetSchemaMergingExample(spark: SparkSession): Unit = {

    import spark.implicits._

    // 创建一个简单的DataFrame,存储到一个分区目录
val squaresDF = spark.sparkContext.makeRDD(1 to 5).map(i => (i, i * i)).toDF("value", "square")
squaresDF.write.parquet("data/test_table/key=1") //在新的分区目录中创建另一个DataFrame,
//添加一个新的列并删除一个现存的列
val cubesDF = spark.sparkContext.makeRDD(6 to 10).map(i => (i, i * i * i)).toDF("value", "cube")
cubesDF.write.parquet("data/test_table/key=2") //读取分区表
val mergedDF = spark.read.option("mergeSchema", "true").parquet("data/test_table")
mergedDF.printSchema() //最终的模式由Parquet文件中的所有3列组成
//分区列出现在分区目录路径中
// root
// |-- value: int (nullable = true)
// |-- square: int (nullable = true)
// |-- cube: int (nullable = true)
// |-- key: int (nullable = true)
// $example off:schema_merging$
}

4, Hive metastore Parquet

     在读取和写入Hive metastore Parquet表格时,Spark SQL将尝试使用自己的Parquet支持而不是Hive SerDe来获得更好的性能。此行为由spark.sql.hive.convertMetastoreParquet配置控制 ,并默认打开。

Hive / Parquet Schema调解

     Hive和Parquet从表模式处理的角度来看,有两个关键的区别。

      1)hive 是不区分大小写的,而Parquet不是

2) Hive认为所有列都是可以空的,而Parquet的可空性是显着的

由于这个原因,在将Hive metastore Parquet表转换为Spark SQL Parquet表时,我们必须将Hive Metastore模式与Parquet模式协调一致。协调规则是:

     在两个模式中具有相同名称的字段必须具有相同的数据类型,而不管是否为空。协调字段应该具有Parquet方面的数据类型,以保证可空性。

协调的模式恰好包含在Hive Metastore模式中定义的那些字段。

     1)仅出现在Parquet模式中的任何字段将被放置在协调的模式中。

     2) 仅在Hive Metastore模式中出现的任何字段才会作为可协调字段添加到协调模式中。
 元数据刷新

        Spark SQL缓存Parquet元数据以获得更好的性能。当Hive Metastore Parquet表转换启用时,这些转换表的元数据也被缓存。如果这些表由Hive或其他外部工具更新,则需要手动刷新以确保一致的元数据。

spark.catalog.refreshTable("my_table")

5,Configuration配置

Parquet的结构可以用做setConf方法上SparkSession或通过运行 SET key=value使用SQL命令



Property Name
Default Meaning
spark.sql.parquet.binaryAsString false 一些其他派奎斯生产系统,特别是Impala,Hive和旧版本的Spark SQL,

在写出Parquet架构时不会区分二进制数据和字符串。该标志告诉Spark SQL

将二进制数据解释为字符串以提供与这些系统的兼容性。
spark.sql.parquet.int96AsTimestamp true  一些Parquet生产系统,特别是Impala和Hive,将时间戳存储到INT96中。

该标志告诉Spark SQL将INT96数据解释为一个时间戳,以提供与这些系统的兼容性。
spark.sql.parquet.cacheMetadata true 打开Parquet模式元数据的缓存。可以加快查询静态数据。
spark.sql.parquet.compression.codec snappy 设置写入Parquet文件时使用的压缩编解码器。可接受的值包括:未压缩,快速,

gzip,lzo。
spark.sql.parquet.filterPushdown true 设置为true时启用Parquet过滤器下推优化。
spark.sql.hive.convertMetastoreParquet true 当设置为false时,Spark SQL将使用Hive SerDe来替代内置支持的Parquet表。
spark.sql.parquet.mergeSchema false

如果为true,则Parquet数据源合并从所有数据文件收集的模式,否则如果

没有摘要文件可用,则从摘要文件或随机数据文件中选取模式。
spark.sql.optimizer.metadataOnly true 如果为true,则启用使用表元数据的仅限元数据查询优化来生成分区列,而

不是表扫描。当扫描的所有列都是分区列时,该查询将适用,并且查询具有

满足不同语义的聚合运算符。

spark SQL (四)数据源 Data Source----Parquet 文件的读取与加载的更多相关文章

  1. asp.net使用httphandler打包多CSS或JS文件以加快页面加载速度

    介绍 使用许多小得JS.CSS文件代替一个庞大的JS或CSS文件来让代码获得更好的可维 护性,这是一个很好的实践.但这样做反过来却损失了网站的性能.虽然你应该将你的Javascript代码写在小文件中 ...

  2. 无法为具有固定名称“MySql.Data.MySqlClient”的 ADO.NET 提供程序加载在应用程序配置文件中注册的实体框架提供程序类型“MySql.Data.MySqlClient.MySqlProviderServices,MySql.Data.Entity.EF6”

    "System.InvalidOperationException"类型的未经处理的异常在 mscorlib.dll 中发生 其他信息: 无法为具有固定名称"MySql. ...

  3. 无法为具有固定名称“System.Data.SqlClient”的 ADO.NET 提供程序加载在应用程序配置文件中注册的实体框架提供程序类型“System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer”。请确保使用限定程序集的名称且该程序集对运行的应用程序可用。有关详细信息,请参阅 http://go.m

    Windows服务中程序发布之后会如下错误: 无法为具有固定名称“System.Data.SqlClient”的 ADO.NET 提供程序加载在应用程序配置文件中注册的实体框架提供程序类型“Syste ...

  4. VC++ 使用WebBrowser控件中html文件以资源形式加载

    . . . . //加载资源文件中的HTML,IDR_HTML1就是HTML文件在资源文件中的ID wchar_t self_path[MAX_PATH] = { }; GetModuleFileNa ...

  5. ASP.NET 打包多CSS或JS文件以加快页面加载速度的Handler

    ASP.NET 打包多CSS或JS文件以加快页面加载速度的Handler, 使用<link type="text/css" rel="Stylesheet" ...

  6. Loader拉取图片,由于redirect重定向,导致策略文件无效 设置checkPolicyFile后还是无效:需要一个策略文件,但在加载此媒体时未设置 checkPolicyFile 标志

    大家好,在这里分享一下flash里边处理redirect的方法. 一般而言,大家不会遇到这个问题,毕竟图片地址一般杠杠的,不会redirect.但昨天在拉取空间的照片就会出现redirect.神啊!! ...

  7. 动态加载/删除css文件以及图片预加载

    动态加载/删除css文件以及图片预加载   功能模块页面   最近,工作中遇到了一个比较奇葩的需求:要在一个页面(PC端)增加一个功能模块,但是这个页面在不久之后要重构,为了新增加的模块可以继续复用, ...

  8. vagramt中同步文件,webpack不热加载

    这是一篇参考文章:https://webpack.js.org/guides/development-vagrant/ 在使用vue-cli+webpack构建的项目中,如何使用vagrant文件同步 ...

  9. JavaScript 文件延迟和异步加载

    JavaScript 文件延迟和异步加载 -般情况下,在文档的 <head> 标签中包含 JavaScript 脚本,或者导入的 JavaScript 文件. 这意味着必须等到全部 Jav ...

随机推荐

  1. tabControl组件的吸顶效果

    最开始,还没有使用better-scroll插件的时候,直接在class中设定了一定的position为sticky,设置一定的top达成了效果.但是,使用better-scroll组件后,这些属性就 ...

  2. 第九章节 BJROBOT 多点导航【ROS全开源阿克曼转向智能网联无人驾驶车】

    1.把小车平放在地板上,用资料里的虚拟机,打开一个终端 ssh 过去主控端启动roslaunch znjrobot bringup.launch. 2.再打开一个终端,ssh 过去主控端启动 rosl ...

  3. 腾讯消息队列CMQ部署与验证

    环境 IP 备注 192.168.1.66 node1 前置机 192.168.1.110 node2 192.168.1.202 node3 架构图 组件介绍 组件 监听端口 access 1200 ...

  4. 机器学习之shape

    shape[:2] 取彩色图片的长和宽 shape[:3]取彩色图片的长和宽和通道 img.shape[0]:图像的垂直高度 img.shape[1]:图像的水平宽度 img.shape[2]:图像的 ...

  5. 【递归】P5461赦免战俘

    题目相关 原题链接:P5461 赦免战俘 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 题目背景 借助反作弊系统,一些在月赛有抄袭作弊行为的选手被抓出来了! 题目描述 现有 \(2 ...

  6. 一网打尽,一文讲通虚拟机VirtualBox及Linux使用

    本文将从虚拟机的选择.安装.Linux系统安装.SSH客户端工具使用四个方面来详细介绍Linux系统在虚拟机下的安装及使用方法,为你在虚拟机下正常使用Linux保驾护航. 1.虚拟机的选择 在讲虚拟机 ...

  7. 阿里云OSS整合

    一.对象存储OSS 为了解决海量数据存储与弹性扩容(主要是静态文件的存储例如图片,语音,视频等),项目中我们通常采用云存储的解决方案- 阿里云OSS. 1.开通"对象存储OSS"服 ...

  8. 万字长文爆肝 DNS 协议!

    试想一个问题,我们人类可以有多少种识别自己的方式?可以通过身份证来识别,可以通过社保卡号来识别,也可以通过驾驶证来识别,尽管我们有多种识别方式,但在特定的环境下,某种识别方法可能比另一种方法更为适合. ...

  9. (三)React Ant Design Pro + .Net5 WebApi:后端环境搭建

    一. 简介 1. 平常用的core webapi 3.1,恰逢.Net5.0正式版发布了,直接开整. 2. 先学习IdentityServer4 .Autofac.EF Core,集成到后台框架里. ...

  10. 企业项目迁移go-zero全攻略(一)

    作者:Mikael 最近发现 golang 社区里出了一个新兴的微服务框架.看了一下官方提供的工具真的很好用,只需要定义好 .api 文件模版代码都可以一键生成,只需要关心业务:同时 core 中的工 ...