与其他格式相比,Parquet格式的优缺点是什么?

kokeuurv  于 2021-05-29  发布在  Hadoop
关注(0)|答案(4)|浏览(627)

apacheParquet地板的特点是:
自我描述
列格式
与语言无关
与avro、序列文件、rc文件等相比,我想要一个格式概述。我已经读过:impala如何与hadoop文件格式一起工作,它提供了一些关于格式的见解,但是我想知道在这些格式中如何访问数据和存储数据。Parquet地板比其他地板有什么优势?

k4aesqcs

k4aesqcs1#

我认为我能描述的主要区别与面向记录和面向列的格式有关。面向记录的格式是我们都习惯的--文本文件,像csv,tsv这样的分隔格式。avro比那些稍微酷一点,因为它可以随着时间的推移改变模式,例如从记录中添加或删除列。各种格式的其他技巧(特别是包括压缩)涉及到是否可以拆分格式——也就是说,您是否可以从数据集中的任何位置读取一个记录块,并且仍然知道它的模式?但这里有更多关于柱状格式的细节,比如Parquet地板。
parquet和其他列格式非常有效地处理常见的hadoop情况。在一个设计良好的关系数据库中,表(数据集)的列数比预期的要多是很常见的——100或200列并不罕见。这是因为我们经常使用hadoop来从关系格式中反规范化数据——是的,您会得到许多重复的值,许多表都被展平为一个表。但是,由于所有的连接都已完成,查询变得更加容易。还有其他优点,比如在时间数据中保留状态。所以不管怎样,在一个表中有一大堆列是很常见的。
假设有132列,其中一些是很长的文本字段,每个不同的列一列接一列,每条记录可能会占用10k。
虽然使用sql查询这些表很容易,但通常您只需要基于几百多列中的几列就可以得到一些记录。例如,您可能需要销售收入>500美元的客户在2月和3月的所有记录。
要以行格式执行此操作,查询需要扫描数据集的每个记录。读取第一行,将记录解析为字段(列)并获取date和sales列,如果满足条件,则将其包含在结果中。重复。如果你有10年(120个月)的历史,你阅读每一条记录只是为了找到其中的2个月。当然,这是一个很好的机会来使用一个年和一个月的分区,但即使如此,您还是在读取和解析这两个月的每条记录/行的10k,以确定客户的销售额是否超过500美元。
在一种列格式中,一条记录的每一列(字段)都与其他同类的列(字段)一起存储,这些列分布在磁盘上的许多不同的块上——一年一列,一个月一列,一个客户员工手册(或其他长文本)列,而其他所有那些让这些记录如此巨大的公司都在各自独立的磁盘空间里,当然还有一起销售的专栏。天哪,日期和月份都是数字,销售额也是——它们只是几个字节。如果我们只需要为每条记录读取几个字节,就可以确定哪些记录与我们的查询匹配,这不是很好吗?柱状储藏室,救命!
即使没有分区,扫描满足我们的查询所需的小字段也是非常快的——它们都是按记录排序的,而且大小都相同,因此磁盘查找包含的记录的数据要少得多。无需通读员工手册和其他长文本字段,只需忽略它们。因此,通过将列而不是行分组,您几乎可以扫描更少的数据。赢了!
但是等等,情况会好转。如果您的查询只需要知道这些值和其他一些值(比如132列中的10列),而不关心employee handbook列,那么一旦选择了要返回的正确记录,现在只需返回到呈现结果所需的10列,而忽略数据集中132列中的其他122列。同样,我们跳过了很多阅读。
(注意:出于这个原因,在进行直接转换时,列格式是一个糟糕的选择,例如,如果您将两个表合并到一个大(ger)结果集中,并将其保存为新表,那么源代码无论如何都会被完全扫描,因此在读性能方面没有太多好处,因为列格式需要记住更多关于内容所在位置的信息,所以它们比类似的行格式使用更多的内存)。
columnar的另一个好处是:数据是分散的。要获得一条记录,您可以让132个工作进程在132个数据块上的132个不同位置读取(和写入)数据。并行化太好了!
现在关键是:当压缩算法能够找到重复的模式时,它的工作会更好。你可以压缩 AABBBBBBCCCCCCCCCCCCCCCC 作为 2A6B16C 但是 ABCABCBCBCBCCCCCCCCCCCCCC 不会变小(好吧,事实上,在这种情况下它会变小,但相信我:-)。所以再一次,少读书。还有写作。
因此,我们读取的数据要少得多,以回答常见的查询,并行读写可能更快,而压缩往往工作得更好。
当您的输入端很大,而您的输出是经过过滤的子集时,columnar就很好了:从大到小就是很好的。当输入和输出大致相同时就没有那么有利了。
但是在我们的例子中,impala使用了我们以前的hive查询,这些查询在5、10、20或30分钟内运行,大多数查询在几秒钟或一分钟内完成。
希望这有助于回答你的问题至少部分!

7kqas0il

7kqas0il2#

选择正确的文件格式对于构建高性能的数据应用程序非常重要。这篇文章中概述的概念延续到Pandas,达斯克,星火,普雷斯托/aws雅典娜。
列修剪
列修剪是一个很大的性能改进,对于基于列的文件格式(parquet,orc)是可能的,而对于基于行的文件格式(csv,avro)是不可能的。
假设您有一个包含100列的数据集,并希望将其中两列读入一个Dataframe。如果数据存储在Parquet文件中,那么您可以使用pandas执行此操作。

import pandas as pd

pd.read_parquet('some_file.parquet', columns = ['id', 'firstname'])

parquet是一种列文件格式,因此pandas可以获取与查询相关的列,并可以跳过其他列。这是一个巨大的性能改进。
如果数据存储在csv文件中,可以这样读取:

import pandas as pd

pd.read_csv('some_file.csv', usecols = ['id', 'firstname'])
``` `usecols` 由于csv文件格式的行特性,无法跳过整列。
spark不要求用户显式列出将在查询中使用的列。spark建立了一个执行计划,并将尽可能地自动利用列修剪。当然,只有在底层文件格式是面向列的情况下,才可能进行列修剪。
人气
spark和pandas内置了csv、json、orc、parquet和文本文件的读写器。他们没有avro的内置读卡器。
avro在hadoop生态系统中很流行。parquet在hadoop生态系统之外获得了巨大的吸引力。例如,三角洲湖项目是建立在Parquet文件。
arrow是一个重要的项目,它使使用各种不同语言(c、c++、go、java、javascript、matlab、python、r、ruby、rust)的parquet文件变得容易,但不支持avro。Parquet文件更容易使用,因为它们受到许多不同项目的支持。
架构
parquet将文件模式存储在文件元数据中。csv文件不存储文件元数据,因此需要向读取器提供模式,或者需要推断模式。提供一个模式是乏味的,而推断一个模式是容易出错/代价高昂的。
avro还将数据模式存储在文件本身中。在文件中使用模式是一个巨大的优势,也是现代数据项目不应该依赖json或csv的原因之一。
列元数据
parquet存储每个列的元数据统计信息,并允许用户添加自己的列元数据。
最小/最大列值元数据允许dask和spark集群计算框架支持的parquet predicate 下推过滤。
下面是如何使用pyarrow获取列统计信息。

import pyarrow.parquet as pq

parquet_file = pq.ParquetFile('some_file.parquet')
print(parquet_file.metadata.row_group(0).column(1).statistics)

<pyarrow._parquet.Statistics object at 0x11ac17eb0>
has_min_max: True
min: 1
max: 9
null_count: 0
distinct_count: 0
num_values: 3
physical_type: INT64
logical_type: None
converted_type (legacy): NONE

复杂列类型
parquet允许复杂的列类型,如数组、字典和嵌套模式。没有一种可靠的方法可以像csv那样以简单的文件格式存储复杂类型。
压缩
列文件格式在行中存储相关类型,因此更易于压缩。这个csv文件比较难压缩。

first_name,age
ken,30
felicia,36
mia,2

当相关类型存储在同一行中时,此数据更容易压缩:

ken,felicia,mia
30,36,2

Parquet文件最常见的压缩与snappy压缩算法。快速压缩的文件是可拆分的,并且可以快速膨胀。大数据系统希望减少磁盘上的文件大小,但同时也希望使其快速膨胀并运行分析查询。
文件的易变性
Parquet文件是不可变的,如下所述。csv文件是可变的。
向csv文件添加一行很容易。你不能
sq1bmfud

sq1bmfud3#

tom的回答非常详细和详尽,但您也可能对allstate insurance进行的有关parquet与avro的简单研究感兴趣,总结如下:
“总的来说,Parquet地板在每项测试中都显示出相似或更好的结果(比avro)。对parquet有利的较大数据集的查询性能差异部分是由于压缩结果造成的;在查询广域数据集时,spark读取的parquet数据要比avro少3.5倍。avro在处理整个数据集时表现不佳,这一点值得怀疑。”

1aaf6o9v

1aaf6o9v4#

avro是hadoop的一种基于行的存储格式。
parquet是hadoop的一种基于列的存储格式。
如果用例通常扫描或检索每个查询中一行中的所有字段,那么avro通常是最佳选择。
如果您的数据集有许多列,并且您的用例通常涉及处理这些列的子集而不是整个记录,那么parquet将针对此类工作进行优化。
来源

相关问题