Apache Parquet 的特点是:
与 Avro、Sequence Files、RC File 等相比,我想要了解这些格式。我已经阅读过:Impala 如何与 Hadoop 文件格式一起工作,它提供了一些关于格式的见解,但我想知道如何以每种格式完成对数据的访问和数据的存储。实木复合地板比其他地板有什么优势?
我认为我可以描述的主要区别与面向记录和面向列的格式有关。面向记录的格式是我们都习惯的——文本文件、分隔格式,如 CSV、TSV。AVRO 比那些稍微酷一些,因为它可以随时间改变模式,例如从记录中添加或删除列。各种格式的其他技巧(尤其包括压缩)涉及是否可以拆分格式 - 也就是说,您是否可以从数据集中的任何位置读取记录块并且仍然知道它的模式?但这里有更多关于 Parquet 等柱状格式的详细信息。
Parquet 和其他列格式可以非常有效地处理常见的 Hadoop 情况。在精心设计的关系数据库中,表(数据集)的列数通常比您预期的多得多——一百或两百列并不罕见。之所以如此,是因为我们经常使用 Hadoop 作为对来自关系格式的数据进行 非规范化 的地方——是的,您会得到很多重复的值,并且许多表都被扁平化为一个表。但是由于所有连接都已计算出来,因此查询变得容易得多。还有其他优点,例如保留时间状态数据。所以无论如何,在一个表中有一大堆列是很常见的。
假设有 132 列,其中一些是非常长的文本字段,每个不同的列一个接一个,每条记录可能用完 10K。
虽然从 SQL 的角度查询这些表很容易,但您通常希望仅基于这数百列中的几列来获取一些记录范围。例如,您可能需要销售额 > 500 美元的客户在 2 月和 3 月的所有记录。
要以行格式执行此操作,查询需要扫描数据集的每条记录。读取第一行,将记录解析为字段(列)并获取日期和销售列,如果满足条件,将其包含在结果中。重复。如果您有 10 年(120 个月)的历史,那么您阅读每条记录只是为了找到其中的 2 个月。当然,这是在年和月上使用分区的好机会,但即便如此,您在这两个月中读取和解析每条记录/行的 10K 只是为了确定客户的销售额是否 > 500 美元。
在列格式中,记录的每一列(字段)与其他列(字段)一起存储,分布在磁盘上的许多不同块中——年份列在一起,月份列在一起,客户员工手册列(或其他列)长文本),以及所有其他使这些记录如此庞大的文件都在磁盘上各自单独的位置,当然还有销售列。哎呀,日期和月份是数字,销售额也是如此——它们只是几个字节。如果我们只需要为每条记录读取几个字节来确定哪些记录与我们的查询匹配,那不是很好吗?柱式存储来救援!
即使没有分区,扫描满足我们查询所需的小字段也非常快——它们都是按记录排序的,并且大小都相同,因此磁盘查找包含记录的数据检查要少得多。无需通读该员工手册和其他长文本字段 - 只需忽略它们即可。因此,通过将列而不是行相互分组,您几乎总是可以扫描更少的数据。赢!
但是等等,它会变得更好。如果您的查询只需要知道这些值和更多值(假设 132 列中的 10 列)并且不关心该员工手册列,那么一旦它选择了要返回的正确记录,它现在只需要去回到渲染结果所需的 10 列,忽略我们数据集中的 132 列中的其他 122 列。同样,我们跳过了很多阅读。
(注意:出于这个原因,在进行直接转换时,列格式是一个糟糕的选择,例如,如果您将所有两个表连接到一个要保存为新表的大(ger)结果集中,源无论如何都会被完全扫描,因此在读取性能方面没有太多好处,而且由于列格式需要记住更多关于内容的位置,它们比类似的行格式使用更多的内存)。
列式的另一个好处:数据是分散的。要获得一条记录,您可以让 132 个工作人员在 132 个数据块上的 132 个不同位置读取(和写入)数据。是的并行化!
现在最重要的是:当压缩算法可以找到重复模式时,它的效果会更好。您可以压缩但不会变小(实际上,在这种情况下它会压缩,但相信我:-))AABBBBBBCCCCCCCCCCCCCCCC。所以再一次,少读书。还有写作。2A6B16C``ABCABCBCBCBCCCCCCCCCCCCCC
AABBBBBBCCCCCCCCCCCCCCCC
2A6B16C``ABCABCBCBCBCCCCCCCCCCCCCC
所以我们读取的数据要少得多来回答常见的查询,并行读取和写入可能会更快,并且压缩往往会更好地工作。
当您的输入端很大时,列式非常好,而您的输出是一个过滤的子集:从大到小是很好的。当输入和输出大致相同时没有那么有用。
但在我们的案例中,Impala 采用了我们在 5、10、20 或 30 分钟内运行的旧 Hive 查询,并且在几秒或一分钟内完成了大部分查询。
希望这有助于至少回答您的部分问题!