现在,由于Spark 2.4内置支持Avro格式,我正在考虑将数据湖中一些通常查询/连接整行而不是特定列聚合的数据集的格式从Parquet更改为Avro。然而,大部分对数据的操作都是通过Spark进行的,据我了解,Spark的内存缓存和计算是基于列格式化的数据完成的。在这方面,Parquet是否提供了性能提升,而Avro则会产生某种形式的数据“转换”惩罚?在这方面,还有哪些其他方面的考虑需要注意?
这两种格式在不同的限制条件下表现出色,但具有强类型和模式以及二进制编码等共同点。就其基本形式而言,它可以归结为以下区别:
如果您已经有了数据并且调整了摄取过程以编写Parquet文件,则在数据摄取(延迟)不成为问题之前,最好仍然使用Parquet。
典型用法实际上是将Parquet和Avro混合使用。最近到达的新数据存储为Avro文件,因为这使得数据立即可用于数据湖。更历史悠久的数据则根据需要(例如每天)转换为Parquet文件,因为它们更小,加载最高效,但只能按批次写入。在处理此数据时,您将其作为两个表的联合加载到Spark中。因此,您可以在Parquet的高效读取与Avro的即时数据可用性之间获得利益。这种模式通常由像 Uber's Hudi 或 Apache Iceberg (incubating) 这样的表格式隐藏。