Spark:Avro vs Parquet 性能

Spark: Avro vs Parquet performance

现在 Spark 2.4 内置了对 Avro 格式的支持,我正在考虑更改我的数据湖中某些数据集的格式——那些通常 queried/joined 整行而不是特定的列聚合 - 从 Parquet 到 Avro。

但是,数据之上的大部分工作都是通过 Spark 完成的,据我了解,Spark 的内存缓存和计算是在柱状格式的数据上完成的。 Parquet 是否在这方面提供了性能提升,而 Avro 会招致某种数据 "transformation" 惩罚?在这方面我还应该注意哪些其他注意事项?

这两种格式在不同的约束条件下都表现出色,但它们具有强类型、模式和二进制编码等共同点。在其基本形式中,它归结为这种差异化:

  • Avro 是一种逐行格式。由此可见,您可以逐行附加到现有文件。然后,所有处理这些文件的读者也可以立即看到这些按行添加的内容。当您有一个以流式(非批处理)方式写入数据湖的进程时,Avro 是最佳选择。
  • Parquet 是一种柱状格式,其文件不可追加。这意味着对于新到达的记录,您必须始终创建新文件。作为这种行为的交换,Parquet 带来了几个好处。数据以列式方式存储,压缩和编码(简单类型感知、低 cpu 但高效压缩)应用于每一列。因此 Parquet 文件将比 Avro 文件小得多。 Parquet 还写出基本统计数据,当您从中加载数据时,您可以将部分选择下推到 I/O。然后只从磁盘加载必要的行集。由于 Parquet 已经采用柱状方式并且大多数内存中结构也将是柱状的,因此从它们加载数据通常要快得多。

由于您已经拥有数据并且摄取过程已调整为写入 Parquet 文件,因此只要数据摄取(延迟)不会成为您的问题,您最好继续使用 Parquet。

一个典型的用法实际上是混合使用 Parquet 和 Avro。最近新到达的数据存储为 Avro 文件,因为这使得数据立即可用于数据湖。更多的历史数据被转化为例如每天写入 Parquet 文件,因为它们更小且加载效率最高,但只能分批写入。在处理这些数据时,您可以将它们作为两个 table 的并集加载到 Spark 中。因此,您将受益于 Parquet 的高效读取以及 Avro 的即时数据可用性。这种模式通常被 table 格式隐藏,例如由 Netflix 发起的 Uber's Hudi or Apache Iceberg (incubating)