Parquet文件详解

1、parquet文件简介

Apache Parquet是Apache Hadoop生态系统的一种免费的开源面向列的数据存储格式。 它类似于Hadoop中可用的其他列存储文件格式,如RCFile格式和ORC格式。

Apache Parquet 是由 Twitter 和 Cloudera 最先发起并合作开发的列存项目,也是 2010 年 Google 发表的 Dremel 论文中描述的内部列存格式的开源实现。和一些传统的列式存储(C-Store、MonetDB 等)系统相比,Dremel/Parquet 最大的贡献是支持嵌套格式数据(Nested Data)的列式存储。嵌套格式可以很自然的描述互联网和科学计算等领域的数据,Dremel/Parquet "原生"的支持嵌套格式数据减少了规则化、重新组合这些大规模数据的代价。

Parquet 的设计与计算框架、数据模型以及编程语言无关,可以与任意项目集成,因此应用广泛。目前已经是 Hadoop 大数据生态圈列式存储的事实标准。

行存和列存的区别

下图是拥有 A/B/C 3 个字段的简单示意表:

在面向行的存储中,例如csv文件,每列的数据依次排成一行,行的存储方式如下所示:

而在面向列的存储中,相同列的数据存储在一起,列的存储如下所示,

从上图,显而易见,行存适用于数据整行读取场景,而列存更适用于读取部分列数据(统计分析等)的场景。

parquet文件的优势

有这样一句话流传:如果说 HDFS 是大数据时代文件系统的事实标准,Parquet 就是大数据时代存储格式的事实标准。Parquet 这种列存的使用场景如下:

  1. Parquet 是一种支持嵌套结构的列式存储格式
  2. 非常适用于 OLAP 场景,按列存储和按列扫描

Parquet 这种列存的特点或优势主要体现在两方面

  1. 更高的压缩比
    列存使得更容易对每个列使用高效的压缩和编码,降低磁盘空间。(网上的case是不压缩、gzip、snappy分别能达到11/27/19的压缩比)
  2. 更小的IO操作
    使用映射下推和谓词下推,只读取需要的列,跳过不满足条件的列,能够减少不必要的数据扫描,带来性能的提升并在表字段比较多的时候更加明显。

关于映射下推与谓词下推: 映射下推,这是列式存储最突出的优势,是指在获取数据时只需要扫描需要的列,不用全部扫描。

谓词下推,是指通过将一些过滤条件尽可能的在最底层执行以减少结果集。谓词就是指这些过滤条件,即返回bool:true和false的表达式,比如SQL中的大于小于等于、Like、Is Null等。

2、parquet文件结构

从内容和元数据的角度来看,Parquet文件主要包含两部分内容:

  1. data
  2. metadata
    data是文件中的数据,metadata是文件的元数据信息。数据data首先写入文件,元数据metadata最后写入文件。

    图一

    图二

从图一和图二所示,一个Parquet有可以分为以下的3个部分:

  1. Header文件头信息
  2. Data Block数据信息
  3. Footer尾部信息
    一个Parquet一般主要包含一个header,一个Data以及一个footer。其中一个Data包含多个Row Group。

Header

header中包含了一个4-byte的magic number(PAR1),这个magic number代表当前该文件是是Parquet格式。

Data Block

Data Block是文件存放具体内容的位置,其中就涉及了Parquet文件的结构,是非常重要的部分。针对文件的存储结构展开说明,
关于parquet文件结构的术语如下:

  1. Block (hdfs Block): 表示hdfs中的块,描述该文件格式的含义不变。该文件格式被设计成在hdfs上很好地工作。
  2. File: hdfs文件,必须包含文件的元数据。它不需要实际包含数据。
  3. 行组(Row Group): 数据的逻辑水平分区。行组没有保证的物理结构。行组由数据集中每一列的列块组成。一个行组中包含的具体行数是不确定的
  4. 列块(Colunm Chunk): 特定列的数据块。它们位于特定的行组中,并保证在文件中是连续的。
  5. 页(Pages): 列块被划分为页。从概念上讲,页面是一个不可分割的单元,压缩和编码都是针对Page进行的。列块中可以有多个分页类型。

官网文件结构图如下所示,其中一个File包含多个Row groups行组,一个行组中包含多个列块,一个列块对应一列数据,并且一个列块中有多个数据页Page,数据页Page才是文件存放的基本单位,数据页可以进行数据压缩和编码。下图的左边和右边合起来是一个完整的文件,左边在上面,右边在下面。

如上图所示,Parquet 的存储模型主要由 **行组(Row Group)、列块(Column Chuck)、页(Page)**组成。Block和File与Parquet文件结构关系不大。

1、行组,Row Group:一个完整的Parquet文件在水平方向上将被划分为一个或者多个行组,默认一个行组的大小与 HDFS Block 块大小对齐,主要是为了保证Parquet一个行组会被一个Mapper 处理。一个行组中有多少行,是不确定的,和行组以及列块的大小有关系。

2、列块,Column Chunk:行组中的每一列都是一个列块,行组中有n列,就会有n个列块,不过这个n个列块的名字可能一样的,一个列块具有相同的数据类型。

3、页,Page:Parquet 是页存储方式,每一个列块包含一个或者多个页,一个页是最小的编码单位,同一列块的不同页可以使用不同的编码方式。压缩和编码都是针对Page进行的。

也可以用以下的方式显示文件的机构:

java 复制代码
4-byte magic number "PAR1"

<RowGroup-1 Column 1 Chunk 1-1 + Column Metadata>
<RowGroup-1 Column 2 Chunk 1-2 + Column Metadata>
<RowGroup-1 Column N Chunk 1-3 + Column Metadata>

<RowGroup-2 Column 1 Chunk 2-1 + Column Metadata>
<RowGroup-2 Column 2 Chunk 2-2 + Column Metadata>
<RowGroup-2 Column N Chunk 2-3 + Column Metadata>

<RowGroup-M Column 1 Chunk M-1 + Column Metadata>
<RowGroup-M Column 2 Chunk M-2 + Column Metadata>
<RowGroup-M Column N Chunk M-3 + Column Metadata>

File Metadata
4-byte length in bytes of file metadata
4-byte magic number "PAR1"

整个文件有 N 个列,整个文件被划分成M 个行组,每个行组都有N个列,行组中的每个列只有一个Chunk,一个行组就有N个Chunk。文件的元数据信息存储在数据之后,包含了所有列块元数据信息的起始位置。读取的时候首先从文件末尾读取文件元数据信息,再从元数据总其中找到某一个需要的 Column Chunk 信息,并依次读取。

Parquet文件中的数据被划分为多个Row Group。这些Row Group由一个或多个column chunks组成,column chunks对应于数据集中的一列。每个column chunks的数据以page的形式写入。每个pages只包含特定列的值,因此pages是非常好的压缩候选对象,因为它们包含类似的值。

FOOTER

文件的所有元数据信息保存在footer中。footer中的元数据包括version、schema、任何额外的键-值对,以及列元数据。列元数据包括类型、路径、编码、值的数量、压缩大小等。Footer中除了文件元数据之外,它还有一个4字节字段长度的footer length,以及一个4字节的魔术字(PAR1)。

3、parquet文件的元数据(metadata)内容

4、schema的讲解和使用

相关推荐
Themberfue3 分钟前
基础算法之双指针--Java实现(下)--LeetCode题解:有效三角形的个数-查找总价格为目标值的两个商品-三数之和-四数之和
java·开发语言·学习·算法·leetcode·双指针
深山夕照深秋雨mo11 分钟前
在Java中操作Redis
java·开发语言·redis
努力的布布17 分钟前
SpringMVC源码-AbstractHandlerMethodMapping处理器映射器将@Controller修饰类方法存储到处理器映射器
java·后端·spring
xujinwei_gingko17 分钟前
Spring MVC 常用注解
java·spring·mvc
PacosonSWJTU22 分钟前
spring揭秘25-springmvc03-其他组件(文件上传+拦截器+处理器适配器+异常统一处理)
java·后端·springmvc
PacosonSWJTU24 分钟前
spring揭秘26-springmvc06-springmvc注解驱动的web应用
java·spring·springmvc
原野心存1 小时前
java基础进阶——继承、多态、异常捕获(2)
java·java基础知识·java代码审计
进阶的架构师1 小时前
互联网Java工程师面试题及答案整理(2024年最新版)
java·开发语言
黄俊懿1 小时前
【深入理解SpringCloud微服务】手写实现各种限流算法——固定时间窗、滑动时间窗、令牌桶算法、漏桶算法
java·后端·算法·spring cloud·微服务·架构
木子02041 小时前
java高并发场景RabbitMQ的使用
java·开发语言