镶木地板格式与其他格式相比有哪些优缺点?

Ani*_*non 112 hadoop file hdfs avro parquet

Apache Parquet的特点是:

  • 自描述
  • 列式格式
  • 与语言无关

与Avro,序列文件,RC文件等相比.我想要格式的概述.我已经读过:Impala如何与Hadoop文件格式配合使用,它提供了一些格式的见解,但我想知道如何以这些格式完成数据访问和数据存储.木地板如何优于其他木地板?

Tom*_*son 241

我认为我能描述的主要区别与面向记录和面向列的格式有关.面向记录的格式是我们习惯的 - 文本文件,CSV,TSV等分隔格式.AVRO比那些稍微冷,因为它可以随时间改变模式,例如添加或删除记录中的列.各种格式的其他技巧(特别是包括压缩)涉及是否可以拆分格式 - 也就是说,您是否可以从数据集中的任何位置读取记录块并仍然知道它的架构?但这里有关于Parquet等柱状格式的更多细节.

Parquet和其他列式格式可以非常有效地处理常见的Hadoop情况.通常情况下,表(数据集)的列数比设计良好的关系数据库中的列多得多 - 一百或两百列并不罕见.之所以如此,是因为我们经常使用Hadoop作为从关系格式对数据进行非规范化的地方- 是的,你会得到很多重复的值,而且很多表都被扁平化为一个.但是查询变得更容易,因为所有连接都已解决.还有其他优点,例如保留状态及时数据.所以无论如何,在桌子上放置一大堆柱子是很常见的.

假设有132列,其中一些是非常长的文本字段,每个不同的列一个跟随另一个列,每个记录使用大约10K.

虽然从SQL角度来看查询这些表很容易,但通常只需要基于这些百余列中的少数列来获取一些记录.例如,对于销售额> 500美元的客户,您可能需要2月和3月的所有记录.

要以行格式执行此操作,查询将需要扫描数据集的每个记录.读取第一行,将记录解析为字段(列)并获取日期和销售列,如果满足条件,则将其包含在结果中.重复.如果您有10年(120个月)的历史记录,那么您正在阅读每一条记录,只是为了找到其中的两个月.当然,这是一个很好的机会,可以在年份和月份上使用分区,但即使这样,您也会在这两个月内阅读并解析每个记录/行的10K,以确定客户的销售额是否超过500美元.

在列式格式中,记录的每个列(字段)与其他类型一起存储,遍布磁盘上的许多不同块 - 一年中的列,一起的列,一起用于客户员工手册的列(或其他这些记录如此巨大的所有其他记录都在磁盘上各自独立的位置,当然也包括销售列.哎呀,日期和月份都是数字,销售也是如此 - 它们只是几个字节.如果我们只需要为每条记录读取几个字节来确定哪些记录与我们的查询匹配,那不是很好吗?柱状存储到救援!

即使没有分区,扫描满足我们查询所需的小字段也是超快的 - 它们全部按记录顺序排列,并且大小相同,因此磁盘搜索包含记录的数据检查的次数要少得多.无需阅读该员工手册和其他长文本字段 - 只需忽略它们即可.因此,通过将列彼此分组而不是行,您几乎总能扫描较少的数据.赢得!

但等等,它变得更好.如果您的查询只需要知道这些值以及更多(比如132列中的10个)并且不关心该员工手册列,一旦它选择了正确的记录返回,它现在只需要去返回到需要渲染结果的10列,忽略数据集中132的其他122列.我们再次跳过大量的阅读.

(注意:出于这个原因,在进行直接转换时,柱状格式是一个糟糕的选择,例如,如果您将所有两个表连接成一个大的(ger)结果集,并将其保存为新表,则源无论如何都要完全扫描,因此读取性能没有太大的好处,并且因为柱状格式需要更多地记住它们的位置,所以它们使用的内存比类似的行格式更多.

柱状的另一个好处是:数据传播.要获得单个记录,您可以让132名工作人员从132个数据块上的132个不同位置读取(和写入)数据.是和平化!

现在,对于紧要关头:压缩算法在找到重复模式时效果会更好.你可以压缩AABBBBBBCCCCCCCCCCCCCCCC,2A6B16CABCABCBCBCBCCCCCCCCCCCCCC不会变得那么小(实际上,在这种情况下它会,但相信我:-)).所以再一次,少阅读.还写作.

因此,我们读取了很少的数据来回答常见查询,并行读取和写入的速度可能更快,压缩往往更好.

当输入端很大时,柱状很棒,输出是一个经过滤的子集:从大到小都很棒.当输入和输出大致相同时,效果不佳.

但在我们的案例中,Impala采用了我们在5,10,20或30分钟内运行的旧H​​ive查询,并在几秒钟或一分钟内完成.

希望这有助于回答至少部分问题!

  • 优秀.谢谢.许多apache项目文档都缺少一个非常有用的摘要..你提到:"小字段......按记录顺序排列".假设我有一个简单的userid表:long和age:int,并希望找到某个年龄段之间的所有用户.这里我有两列.我是否需要指定何时是排序索引,还是所有列都可以高效转换? (5认同)

小智 42

Avro是Hadoop的基于行的存储格式.

Parquet是Hadoop的基于列的存储格式.

如果您的用例通常扫描或检索每个查询中的一行中的所有字段,则Avro通常是最佳选择.

如果您的数据集包含许多列,并且您的用例通常涉及使用这些列的子集而不是整个记录,则Parquet会针对此类工作进行优化.

资源


Jus*_*lyn 18

汤姆的答案非常详细和详尽,但您可能也对这项关于在Allstate保险公司完成的Parquet vs Avro的简单研究感兴趣,总结如下:

"总体而言,Parquet在每次测试中都显示出相似或更好的结果[比Avro].在Parquet中较大数据集的查询性能差异部分归因于压缩结果;在查询宽数据集时,Spark必须读取3.5x Parquet的数据少于Avro.在处理整个数据集时,Avro表现不佳.


Pow*_*ers 8

选择正确的文件格式对于构建高性能数据应用程序很重要。本文中概述的概念适用于 Pandas、Dask、Spark 和 Presto/AWS Athena。

列修剪

列修剪是一项重大的性能改进,对于基于列的文件格式(Parquet、ORC)是可能的,而对于基于行的文件格式(CSV、Avro)则不可能。

假设您有一个包含 100 列的数据集,并且想要将其中的两列读入 DataFrame。如果数据存储在 Parquet 文件中,您可以通过以下方式使用 Pandas 执行此操作。

import pandas as pd

pd.read_parquet('some_file.parquet', columns = ['id', 'firstname'])
Run Code Online (Sandbox Code Playgroud)

Parquet 是一种柱状文件格式,因此 Pandas 可以抓取与查询相关的列,并可以跳过其他列。这是一个巨大的性能改进。

如果数据存储在 CSV 文件中,您可以这样读取:

import pandas as pd

pd.read_csv('some_file.csv', usecols = ['id', 'firstname'])
Run Code Online (Sandbox Code Playgroud)

usecols 由于 CSV 文件格式的行性质,无法跳过整列。

Spark 不要求用户明确列出将在查询中使用的列。Spark 会建立一个执行计划,并会在可能的情况下自动利用列修剪。当然,只有当底层文件格式是面向列的时,列修剪才可能。

人气

Spark 和 Pandas 具有用于 CSV、JSON、ORC、Parquet 和文本文件的内置阅读器编写器。他们没有 Avro 的内置阅读器。

Avro 在 Hadoop 生态系统中很受欢迎。Parquet 在 Hadoop 生态系统之外获得了巨大的吸引力。例如,Delta Lake项目是基于 Parquet 文件构建的。

Arrow是一个重要的项目,它可以轻松地使用各种不同的语言(C、C++、Go、Java、JavaScript、MATLAB、Python、R、Ruby、Rust)处理 Parquet 文件,但不支持 Avro。Parquet 文件更易于使用,因为它们受到许多不同项目的支持。

架构

Parquet 将文件架构存储在文件元数据中。CSV 文件不存储文件元数据,因此需要向读者提供架构或需要推断架构。提供模式很乏味,推断模式容易出错/代价高昂。

Avro 还将数据模式存储在文件本身中。在文件中包含架构是一个巨大的优势,也是现代数据项目不应依赖 JSON 或 CSV 的原因之一。

列元数据

Parquet 存储每个列的元数据统计信息,允许用户添加自己的列元数据

最小/最大列值元数据允许 Dask 和 Spark 集群计算框架支持的 Parquet 谓词下推过滤。

以下是如何使用 PyArrow 获取列统计信息。

import pyarrow.parquet as pq

parquet_file = pq.ParquetFile('some_file.parquet')
print(parquet_file.metadata.row_group(0).column(1).statistics)
Run Code Online (Sandbox Code Playgroud)
<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
Run Code Online (Sandbox Code Playgroud)

复杂的列类型

Parquet 允许复杂的列类型,如数组、字典和嵌套模式。没有可靠的方法以简单的文件格式(如 CSV)存储复杂类型。

压缩

列式文件格式将相关类型存储在行中,因此更易于压缩。此 CSV 文件相对难以压缩。

first_name,age
ken,30
felicia,36
mia,2
Run Code Online (Sandbox Code Playgroud)

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

ken,felicia,mia
30,36,2
Run Code Online (Sandbox Code Playgroud)

Parquet 文件最常使用 Snappy 压缩算法进行压缩。Snappy 压缩文件可拆分且快速膨胀。大数据系统希望减少磁盘上的文件大小,但也希望快速膨胀并运行分析查询。

文件的可变性质

Parquet 文件是不可变的,如此处所述。CSV 文件是可变的。

向 CSV 文件添加一行很容易。您不能轻松地向 Parquet 文件添加一行。

数据湖

在大数据环境中,您将处理成百上千个 Parquet 文件。文件的磁盘分区、避免大文件和压缩小文件很重要。数据的最佳磁盘布局取决于您的查询模式。