第63课:Spark SQL下Parquet内幕深度解密学习笔记
本期内容:
1. SparkSQL下的Parquet意义再思考
2. SparkSQL下的Parquet内幕解密
一.SparkSQL下的Parquet意义再思考
Twitter用Parquet节省了70%存储费用。
1. 如果HDFS是大数据时代分布式文件系统存储的事实标准的话,Parquet则是整个大数据时代文件存储格式的事实标准
2. 速度更快:从使用SparkSQL操作普通文件CSV和Parquet文件的速度对比上来看,绝大多数情况下,使用Parquet会比使用CSV等普通文件速度提升10倍左右(在一些变通文件系统无法在Spark上成功运行的情况下,使用Parquet很多时候都可以成功运行)。
3. Parquet的压缩技术非常稳定出色。SparkSQL本身也会做压缩,但压缩过程中会出问题。在SparkSQL中对压缩技术的处理可能无法正常完成的工作(例如会导致Lost Task、Lost Executor),但是此时如果使用Parquet就可以正常完成。Lost Task、Lost Executor会导致任务重试。如果文件格式转换为Parquet,其他任何设置都不改变就可以了。
数据输入量的不同会影响调度。有时是有效数据有时是无效数据。
4. 极大减少磁盘IO,通常情况下能够减少75%的存储空间,由此可以极大的减少减少SparkSQL处理数据的时候的数据输入内容,尤其是在Spark1.6.x中下推过滤器(处理前就把数据过滤。下推是在框架优化的时候自动处理的)在一些情况下可以极大地进一步减少磁盘IO和内存的占用。SparkSQL已经把parquet作为默认格式了。
95%以上情况都可以使用Parquet。
列式存储每一列都跟其他列无关。
5. Spark1.6.x + Parquet极大的提升了数据扫描的吞吐量,这极大的提高了数据的查找速度。
Spark1.6和Spark1.5.x相比提升了1倍速度。在Spark1.6.x中操作Parquet时,
6. 采用Parquet可以极大优化Spark的调度和执行,测试表明Spark如果采用Parquet可以有效减少Stage的执行消耗,同时可以优化执行路径。
二.SparkSQL下的Parquet内幕解密
日志一般都有嵌套数据结构。
日志结构是复杂的嵌套数据类型,例如一个典型的日志的schema有87列,嵌套了7层。所以需要设计一种列式存储格式,既能支持关系型数据(简单数据类型),又能支持复杂的嵌套类型的数据,同时能够适配多种数据处理框架
1. 列式存储是以什么基本格式来存储数据的?
=>1.数据本身,2.数据的元数据,3.引擎
Parquet表现上是树状数据结构,内部有元数据的Table,
2. 在具体的Parquet文件存储的时候有三个核心组成部分:
A)Storage Format:Parquet定义了具体的数据内部的类型和存储格式
B)对象模型转换器(object model converters):在Parquet中负责计算框架中数据对象和Parquet文件中具体数据类型的映射。
这部分功能由parquet-mr项目来实现,主要完成外部对象模型与Parquet内部数据类型的映射。
C)对象模型(object models):在Parquet中具有自己的ObjectModel定义的存储格式,例如Avro具有自己的ObjectModel,但Parquet在处理相关的格式的数据时使用自己的ObjectModel来存储。
映射完成后Parquet会进行自己的Column Encoding然后存储 Parquet格式 文件。
Avro是Hadoop中的一个子项目,也是Apache中一个独立的项目,Avro是一个基于二进制数据传输高性能的中间件。在Hadoop的其他项目中例如HBase(Ref)和Hive(Ref)的Client端与服务端的数据传输也采用了这个工具。Avro是一个数据序列化的系统。Avro 可以将数据结构或对象转化成便于存储或传输的格式。Avro设计之初就用来支持数据密集型应用,适合于远程或本地大规模数据的存储和交换。
完成数据存储本身
对象模型可以简单理解为内存中的数据表示,Avro, Thrift, Protocol Buffers, Hive SerDe, Pig Tuple, Spark SQL InternalRow等这些都是对象模型。Parquet也提供了一个example object model 帮助大家理解。
apache parquet官网http://parquet.apache.org/documentation/latest/提到了:
Motivation
We created Parquet to make the advantages of compressed, efficient columnar data representation available to any project in the Hadoop ecosystem.
Parquet is built from the ground up with complex nested data structures in mind, and uses the record shredding and assembly algorithm described in the Dremel paper. We believe this approach is superior to simple flattening of nested name spaces.
Parquet is built to support very efficient compression and encoding schemes. Multiple projects have demonstrated the performance impact of applying the right compression and encoding scheme to the data. Parquet allows compression schemes to be specified on a per-column level, and is future-proofed to allow adding more encodings as they are invented and implemented.
Parquet is built to be used by anyone. The Hadoop ecosystem is rich with data processing frameworks, and we are not interested in playing favorites. We believe that an efficient, well-implemented columnar storage substrate should be useful to all frameworks without the cost of extensive and difficult to set up dependencies.
Modules
The parquet-format project contains format specifications and Thrift definitions of metadata required to properly read Parquet files.
The parquet-mr project contains multiple sub-modules, which implement the core components of reading and writing a nested, column-oriented data stream, map this core onto the parquet format, and provide Hadoop Input/Output Formats, Pig loaders, and other java-based utilities for interacting with Parquet.
The parquet-compatibility project contains compatibility tests that can be used to verify that implementations in different languages can read and write each other’s files.
4.举例说明:
message AddressBook{
required string owner;
repeated string ownerPhoneNumbers;
repeated proup contacts{
required string name;
optional string phoneNumber;
}
}
required(出现1次),optional(出现0次或者1次),repeated(出现0次或者多次)
这个schema中每条记录表示一个人的AddressBook。有且只有一个owner,owner可以有0个或者多个ownerPhoneNumbers,owner可以有0个或者多个contacts。每个contact有且只有一个name,这个contact的phoneNumber可有可无。
第一点:就存储数据本身而言,只考虑叶子节点,我们的叶子节点owner、ownerPhoneNumber、name、phoneNumber;
第二点:在逻辑上而言Schema实质上是一个Table:
AddressBook | |||
owner | ownerPhoneNumber | Contacts | |
Name | phoneNumber | ||
|
|
|
|
第三点:对于一个Parquet文件而言,数据会被分成Row Group(里面包含很多Column,每个Column具有几个非常重要的特性例如Repetition Level、Definition Level);
第四点:Column在Parquet中是以Page的方式存在的,Page中有Repetition Level、Definition Level等内容;
第五点:Row Group在Parquet中是数据读写的缓存单元,所以对Row Group的设置会极大的影响Parquet的使用速度和效率,所以如果是分析日志的话,我们一般建议把Row Group的缓存大小配置成大约256MB,很多人的配置都是大约1G,如果想最大化的运行效率强烈建议HDFS的Block大小和Row Group一直
record shredding and assembly algorithm
第六点:在实际存储的把一个树状结构,通过巧妙的编码算法,转换成二维表结构
Repetiton Level | Definition Level | Value |
1 | 2 | 18610086859 |
0 | 1 | “Spark” |
0 | 0 | NULL |
以上内容是王家林老师DT大数据梦工厂《 IMF传奇行动》第63课的学习笔记。
王家林老师是Spark、Flink、Docker、Android技术中国区布道师。Spark亚太研究院院长和首席专家,DT大数据梦工厂创始人,Android软硬整合源码级专家,英语发音魔术师,健身狂热爱好者。
微信公众账号:DT_Spark
电话:18610086859
QQ:1740415547
微信号:18610086859
新浪微博:ilovepains