与其他格式相比,实木复合地板格式的优缺点是什么?


136

Apache Parquet的特征是:

  • 自我描述
  • 柱状格式
  • 语言无关

与Avro,Sequence Files,RC File等相比。我想要这些格式的概述。我已经读过:Impala如何与Hadoop文件格式一起使用,它提供了一些有关格式的见解,但是我想知道在每种格式中如何进行数据访问和数据存储。镶木地板比其他镶木地板有什么优势?


2
可以在此演示文稿中找到一个不错的摘要:链接
Dominik

@ ani-menon链接已死。
Sajjad Hossain '18

@SajjadHossain已更新。
阿尼·梅农

Answers:


281

我认为我可以描述的主要区别涉及面向记录和面向列的格式。面向记录的格式是我们常用的格式-文本文件,分隔格式,如CSV,TSV。AVRO比那些稍微凉爽些,因为它可以随时间更改架构,例如从记录中添加或删除列。各种格式(尤其是压缩)的其他技巧还涉及一种格式是否可以拆分-也就是说,您是否可以从数据集中的任何位置读取记录块并仍然知道其模式?但是,这里有有关Parquet等列格式的更多详细信息。

Parquet和其他列式格式可以非常有效地处理常见的Hadoop情况。通常,表(数据集)的列要比设计良好的关系数据库中所期望的要多得多-一百或两百列并不罕见。之所以如此,是因为我们经常使用Hadoop作为从关系格式对数据进行非规范化的地方-是的,您会得到很多重复的值,并且许多表都被压平为一个表。但是,由于所有联接都已计算出来,因此查询起来变得容易得多。还有其他优点,例如保留时间状态数据。因此,无论如何,在表中包含大量的列是很常见的。

假设有132列,其中一些实际上是很长的文本字段,每个不同的列一个接一个,并且每条记录可能消耗10K。

从SQL的角度来看,查询这些表很容易,但是通常只希望基于几百个以上的列中的一些来获取一定范围的记录。例如,对于销售> $ 500的客户,您可能想要二月和三月的所有记录。

为此,查询将需要扫描数据集的每条记录。阅读第一行,将记录解析为字段(列),并获取日期和销售列,如果满足条件,则将其包括在结果中。重复。如果您有10年(120个月)的历史记录,那么您正在阅读每条记录,只是发现其中的2个月。当然,这是按年和月使用分区的绝好机会,但是即使如此,您正在读取并解析这两个月的每条记录/行的10K,以了解客户的销售额是否大于$ 500。

以列格式,记录的每个列(字段)都与同类记录一起存储,分布在磁盘上的许多不同块上-一年在一起的列,月份在一起的列,客户员工手册的列(或其他)长文本),以及所有其他使这些记录变得如此庞大的记录,它们都放在磁盘上各自单独的位置,当然也有待销售的列。嗯,日期和月份是数字,销售额也是如此-它们只是几个字节。如果我们只需要为每个记录读取几个字节来确定哪些记录与我们的查询匹配,那不是很好吗?柱状储藏物可以营救!

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

但是,等等,情况会变得更好。如果您的查询只需要知道这些值和更多值(例如132列中的10列)并且不关心该员工手册列,那么一旦它选择了要返回的正确记录,现在只需要去返回到显示结果所需的10列,而忽略了数据集中132个中的其他122个。同样,我们跳过了大量阅读。

(注意:由于这个原因,列式格式在进行直接转换时是一个糟糕的选择,例如,如果要将两个表全部都合并到一个大(ger)结果集中,然后将其另存为新表,则源无论如何都将被完全扫描,因此读取性能并没有太多好处,而且由于列格式需要记住更多东西的位置,因此它们比类似的行格式使用更多的内存。

柱状图的另一个好处是:数据分散分布。要获得一条记录,您可以让132个工作人员分别从132个数据块中的132个不同位置读取/写入数据。是的并行化!

现在,对于敲门者来说:当压缩算法可以找到重复的模式时,其压缩算法会更好地工作。您可以压缩AABBBBBBCCCCCCCCCCCCCCCC到最小,2A6B16CABCABCBCBCBCCCCCCCCCCCCCC不会变小(嗯,实际上,在这种情况下会压缩,但是请相信我:-))。因此,再次减少阅读量。还有写作。

因此,我们读取的数据较少以回答常见查询,并行读取和写入的速度可能会更快,并且压缩的效果会更好。

当您的输入端很大时,列式就很好,而您的输出是一个过滤后的子集:从大到小都很棒。当输入和输出大致相同时,效果不佳。

但是在我们的案例中,Impala接受了我们的旧的Hive查询,这些查询在5、10、20或30分钟内运行,并在几秒钟或一分钟内完成了大部分。

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


7
优秀的。谢谢。是一个非常有用的摘要,许多apache项目文档中都缺少该摘要。您提到:“小字段...都是按记录排列的”。假设我有一个简单的userid:long和age:int表,并且想要查找某个年龄之间的所有用户。在这里,我有两列。我需要指定排序索引的时间,还是可以有效索引所有列?
user48956'7

1
如果我在时间序列中使用镶木地板怎么办?几列(100+),每列一个具有不同频率(100hz至0.25 hz)的传感器数据。这是一个明智的决定吗?
guilhermecgs '18

53

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

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

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

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

资源


26

Tom的答案非常详尽且详尽无遗,但您可能对Allstate Insurance进行的有关Parquet vs Avro的这项简单研究感兴趣,摘要如下:

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.