spark SQL (四)数据源 Data Source----Parquet 文件的读取与加载
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 文件的读取与加载的更多相关文章
- asp.net使用httphandler打包多CSS或JS文件以加快页面加载速度
介绍 使用许多小得JS.CSS文件代替一个庞大的JS或CSS文件来让代码获得更好的可维 护性,这是一个很好的实践.但这样做反过来却损失了网站的性能.虽然你应该将你的Javascript代码写在小文件中 ...
- 无法为具有固定名称“MySql.Data.MySqlClient”的 ADO.NET 提供程序加载在应用程序配置文件中注册的实体框架提供程序类型“MySql.Data.MySqlClient.MySqlProviderServices,MySql.Data.Entity.EF6”
"System.InvalidOperationException"类型的未经处理的异常在 mscorlib.dll 中发生 其他信息: 无法为具有固定名称"MySql. ...
- 无法为具有固定名称“System.Data.SqlClient”的 ADO.NET 提供程序加载在应用程序配置文件中注册的实体框架提供程序类型“System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer”。请确保使用限定程序集的名称且该程序集对运行的应用程序可用。有关详细信息,请参阅 http://go.m
Windows服务中程序发布之后会如下错误: 无法为具有固定名称“System.Data.SqlClient”的 ADO.NET 提供程序加载在应用程序配置文件中注册的实体框架提供程序类型“Syste ...
- VC++ 使用WebBrowser控件中html文件以资源形式加载
. . . . //加载资源文件中的HTML,IDR_HTML1就是HTML文件在资源文件中的ID wchar_t self_path[MAX_PATH] = { }; GetModuleFileNa ...
- ASP.NET 打包多CSS或JS文件以加快页面加载速度的Handler
ASP.NET 打包多CSS或JS文件以加快页面加载速度的Handler, 使用<link type="text/css" rel="Stylesheet" ...
- Loader拉取图片,由于redirect重定向,导致策略文件无效 设置checkPolicyFile后还是无效:需要一个策略文件,但在加载此媒体时未设置 checkPolicyFile 标志
大家好,在这里分享一下flash里边处理redirect的方法. 一般而言,大家不会遇到这个问题,毕竟图片地址一般杠杠的,不会redirect.但昨天在拉取空间的照片就会出现redirect.神啊!! ...
- 动态加载/删除css文件以及图片预加载
动态加载/删除css文件以及图片预加载 功能模块页面 最近,工作中遇到了一个比较奇葩的需求:要在一个页面(PC端)增加一个功能模块,但是这个页面在不久之后要重构,为了新增加的模块可以继续复用, ...
- vagramt中同步文件,webpack不热加载
这是一篇参考文章:https://webpack.js.org/guides/development-vagrant/ 在使用vue-cli+webpack构建的项目中,如何使用vagrant文件同步 ...
- JavaScript 文件延迟和异步加载
JavaScript 文件延迟和异步加载 -般情况下,在文档的 <head> 标签中包含 JavaScript 脚本,或者导入的 JavaScript 文件. 这意味着必须等到全部 Jav ...
随机推荐
- TIDB简介
摘自https://pingcap.com/docs-cn/ TiDB 是 PingCAP 公司设计的开源分布式 HTAP (Hybrid Transactional and Analytical P ...
- 聊聊ERP的VIP卡充值的那些事
我们相信许多客户朋友,不管使用什么品牌的ERP系统,可能都有经历过各种各样的操作痛点,以及在某个阶段之前的功能无法满足现有的操作需求.今天我们就聊聊VIP卡充值操作遇到的一些问题以及相关解决方案,最大 ...
- Erlang那些事儿第3回之我是函数(fun),万物之源MFA
Erlang代码到处都是模式匹配,这把屠龙刀可是Erlang的看家本领.独家绝学,之前在<Erlang那些事儿第1回之我是变量,一次赋值永不改变>文章提到过,Erlang一切皆是模式匹配. ...
- 一个轻量级的.Net Core微服务快速开发的轮子
前言 Adnc是一个轻量级的.Net Core微服务快速开发框架,同时也可以应用于单体架构系统的开发.框架基于JWT认证授权.集成了一系列微服务配套组件,代码简洁.易上手.学习成本低.开箱即用 ...
- C. Three Bags【CF 1467】
传送门 思路:对于一般情况,我们有三个袋子,容易想到把袋子里物品的价值排序.然后贪心,我们想让最后的价值最大,则三个袋子最后都可以剩余一个物品,这三个物品总和需要最大,最好的情况就是三个物品的符号&q ...
- 风炫安全WEB安全学习第二十一节课 存储型XSS讲解
风炫安全WEB安全学习第二十一节课 存储型XSS讲解 存储型XSS演示 存储型XSS,持久化,代码是存储在服务器中的,如在个人信息或发表文章等地方,加入代码,如果没有过滤或过滤不严,那么这些代码将储存 ...
- Let's Encrypt SSL证书申请
当前环境: 阿里云CoreOS 所绑定的域名,解析管理也在阿里这儿,在该文档中使用 example.com 作为示例. Docker 镜像 acme.sh:2.8.8 nginx 申请证书并使用 使用 ...
- 数仓建设中最常用模型--Kimball维度建模详解
数仓建模首推书籍<数据仓库工具箱:维度建模权威指南>,本篇文章参考此书而作.文章首发公众号:五分钟学大数据,公众号中发送"维度建模"即可获取此书籍第三版电子书 先来介绍 ...
- Ocelot一个优秀的.NET API网关框架
1 什么是Ocelot? Ocelot是一个用.NET Core实现并且开源的API网关,它功能强大,包括了:路由.请求聚合.服务发现.认证.鉴权.限流熔断.并内置了负载均衡器与Service Fab ...
- SQL查找连续出现的数字
基于Oracle: 题:编写一个 SQL 查询,查找所有至少连续出现三次的数字. +----+-----+ | Id | Num | +----+-----+ | 1 | 1 | | 2 | 1 | ...