高效的数据处理对于依赖大数据分析做出明智决策的企业和组织至关重要。一个关键因素极大地影响了数据处理性能的是数据的存储格式。本文探讨了不同存储格式(特别是Parquet、Avro和ORC)对在Google Cloud Platform (GCP)上大数据环境中的查询性能和成本的影响。本文提供了基准测试数据,讨论了成本影响,并针对特定用例提出了选择合适格式的建议。
大数据中的存储格式简介
数据存储格式是任何大数据处理环境的基础。它们定义了数据如何存储、读取和写入,直接影响存储效率、查询性能和数据检索速度。在大数据生态系统中,列式格式如Parquet和ORC以及行式格式如Avro被广泛使用,因为它们针对特定类型的查询和处理任务优化了性能。
- Parquet:Parquet是一种优化了读取操作和分析的列式存储格式。在压缩和编码方面非常高效,使其成为优先考虑读取性能和存储效率的场景的理想选择。
- Avro:Avro是一种行式存储格式,设计用于数据序列化。它以其模式演变能力而闻名,通常用于写入操作繁重的场景,其中数据需要快速序列化和反序列化。
- ORC(优化行列式):ORC是一种类似于Parquet的列式存储格式,但优化了读写操作。在压缩方面,ORC非常高效,这降低了存储成本并加快了数据检索速度。
研究目标
这项研究的主要目标是评估在大数据环境中,不同的存储格式(Parquet、Avro、ORC)如何影响查询性能和成本。本文旨在为数据工程师和架构师提供基于各种查询类型和数据量的基准测试,以帮助他们选择最适合其特定用例的格式。
实验设置
为了进行这项研究,我们在Google Cloud Platform(GCP)上使用标准化的设置,以Google Cloud Storage作为数据存储库,使用Google Cloud Dataproc运行Hive和Spark-SQL作业。实验中使用的数据是结构化和半结构化数据的混合,以模仿现实世界的场景。
关键组件
- Google Cloud Storage:用于以不同格式(Parquet、Avro、ORC)存储数据集
- Google Cloud Dataproc:一个管理的Apache Hadoop和Apache Spark服务,用于运行Hive和Spark-SQL作业。
- 数据集:三种不同大小的数据集(10GB、50GB、100GB),数据类型混合。
# Initialize PySpark and set up Google Cloud Storage as file system
from pyspark.sql import SparkSession
spark = SparkSession.builder \
.appName("BigDataQueryPerformance") \
.config("spark.jars.packages", "com.google.cloud.bigdataoss:gcs-connector:hadoop3-2.2.5") \
.getOrCreate()
# Configure the access to Google Cloud Storage
spark.conf.set("fs.gs.impl", "com.google.cloud.hadoop.fs.gcs.GoogleHadoopFileSystem")
spark.conf.set("fs.gs.auth.service.account.enable", "true")
spark.conf.set("google.cloud.auth.service.account.json.keyfile", "/path/to/your-service-account-file.json")
测试查询
- 简单的SELECT查询:从表中检索所有列的基本操作
- 过滤查询:带有WHERE子句的SELECT查询,用于过滤特定行
- 聚合查询:涉及GROUP BY和诸如SUM、AVG等聚合函数的查询..
- 连接查询:在公共键上连接两个或更多表的查询
结果与分析
1. 简单的SELECT查询
- Parquet:由于其列存储格式,它表现非常出色,这使得可以快速扫描特定列。Parquet文件高度压缩,减少了从磁盘读取的数据量,从而加快了查询执行时间。
# Simple SELECT query on Parquet file
parquet_df.select("column1", "column2").show()
- Avro:Avro的表现中等。作为一种基于行的格式,Avro即使只需要特定列,也必须读取整行。这增加了I/O操作,导致与Parquet和ORC相比,查询性能较慢。
-- Simple SELECT query on Avro file in Hive
CREATE EXTERNAL TABLE avro_table
STORED AS AVRO
LOCATION 'gs://your-bucket/dataset.avro';
SELECT column1, column2 FROM avro_table;
- ORC:ORC的表现与Parquet相似,压缩略好,且优化存储技术提高了读取速度。ORC文件也是列式的,使其适合于仅检索特定列的SELECT查询。
# Simple SELECT query on ORC file
orc_df.select("column1", "column2").show()
2. 过滤查询
- Parquet:由于其列式结构,Parquet保持了其性能优势,能够快速跳过无关的列。然而,为了应用过滤器,需要扫描更多行,这会对性能产生轻微影响。
# Filter query on Parquet file
filtered_parquet_df = parquet_df.filter(parquet_df.column1 == 'some_value')
filtered_parquet_df.show()
- Avro:由于需要读取整行并在所有列上应用筛选器,性能进一步下降,处理时间增加。
-- Filter query on Avro file in Hive
SELECT * FROM avro_table WHERE column1 = 'some_value';
- ORC:由于其谓词下推特性,ORC在筛选查询中略优于Parquet。这一特性允许在数据加载到内存之前,直接在存储层进行筛选。
# Filter query on ORC file
filtered_orc_df = orc_df.filter(orc_df.column1 == 'some_value')
filtered_orc_df.show()
3. 聚合查询
- Parquet:Parquet表现良好,但效率略低于ORC。列式格式通过快速访问所需列,使聚合操作受益,但Parquet缺乏ORC提供的某些内置优化。
# Aggregation query on Parquet file
agg_parquet_df = parquet_df.groupBy("column1").agg({"column2": "sum", "column3": "avg"})
agg_parquet_df.show()
- Avro:由于基于行的存储,Avro落后了。它需要为每行扫描和处理所有列,增加了计算开销。
-- Aggregation query on Avro file in Hive
SELECT column1, SUM(column2), AVG(column3) FROM avro_table GROUP BY column1;
- ORC:在聚合查询中,ORC的表现优于Parquet和Avro。ORC的高级索引和内置压缩算法实现了更快的数据访问和减少了I/O操作,使其非常适合聚合任务。
# Aggregation query on ORC file
agg_orc_df = orc_df.groupBy("column1").agg({"column2": "sum", "column3": "avg"})
agg_orc_df.show()
4. 连接查询
- Parquet:Parquet在连接操作中表现良好,但效率不如ORC,因为其对于连接条件的数据读取优化不足。
# Join query between Parquet and ORC files
joined_df = parquet_df.join(orc_df, parquet_df.key == orc_df.key)
joined_df.show()
- ORC:在连接查询中,ORC表现出色,得益于高级索引和谓词下推功能,这些功能在连接操作期间最小化了扫描和处理的数据量。
# Join query between two ORC files
joined_orc_df = orc_df.join(other_orc_df, orc_df.key == other_orc_df.key)
joined_orc_df.show()
- Avro: Avro 在连接操作上遇到了显著困难,这主要是由于读取完整行的高开销以及对于连接键的列优化不足。
-- Join query between Parquet and Avro files in Hive
SELECT a.column1, b.column2
FROM parquet_table a
JOIN avro_table b
ON a.key = b.key;
存储格式对成本的影响
1. 存储效率和成本
- Parquet 和 ORC(列存储格式)
- 压缩和存储成本:Parquet 和 ORC 都是列存储格式,它们提供很高的压缩率,尤其是对于列中存在许多重复或相似值的 dataset。这种高压缩率减少了整体数据大小,从而降低了存储成本,尤其是在云环境中,存储费用是按 GB 计费的。
- 适用于分析工作负载:由于它们是列式的,这些格式非常适合只频繁查询特定列的分析工作负载。这意味着从存储中读取的数据更少,从而减少了 I/O 操作和相关的成本。
- Avro(基于行的格式)
- 压缩和存储成本:Avro通常提供的压缩率低于像Parquet和ORC这样的列式格式,因为它逐行存储数据。这对于拥有许多列的大型数据集尤其如此,因为必须读取一行中的所有数据,即使只需要其中的一小部分列。
- 更适合写入密集型工作负载:尽管Avro由于压缩率较低可能导致存储成本上升,但它更适合写入密集型工作负载,在这种工作负载中,数据持续被写入或追加。与存储相关的成本可能会通过数据序列化和反序列化的效率提升来抵消。
2. 数据处理性能和成本
- Parquet和ORC(列式格式)
- 降低处理成本:这些格式针对读操作进行了优化,使其在大数据集查询方面非常高效。因为它们只读取查询所需的相关列,所以减少了处理的数据量。这导致了CPU使用率的降低和查询执行时间的缩短,在云环境中,这可以显著降低基于使用情况计费的计算资源的成本。
- 用于成本优化的高级功能:特别是ORC格式,它包含诸如谓词下推和内置统计信息等特性,使查询引擎能够跳过读取不必要的数据。这进一步减少了I/O操作并提高了查询性能,优化了成本。
- Avro(基于行的格式)
- 处理成本较高:由于Avro是基于行的格式,即使只需要少数列,通常也需要进行更多的I/O操作来读取整个行。这可能会导致由于CPU使用率升高和查询执行时间延长而增加计算成本,尤其是在读取密集型环境中。
- 适用于流处理和序列化:尽管查询的处理成本较高,但Avro非常适合流处理和序列化任务,在这些任务中,快速写入速度和模式演化更为关键。
3. 成本分析与定价详情
- 为了量化每种存储格式的影响成本,我们在GCP上进行了一次实验。我们根据GCP的定价模型,计算了每种格式的存储和数据处理相关成本。
- 谷歌云存储成本
- 存储成本:这是根据每种格式存储的数据量来计算的。对于存储在谷歌云存储中的数据,GCP按每GB每月收费。每个格式的压缩比例直接影响这些成本。如Parquet和ORC等列式格式通常比Avro等行式格式有更好的压缩比例,从而降低存储成本。
- 以下是计算存储成本的一个示例:
- Parquet:高压缩比例减少了数据大小,降低了存储成本
- ORC:与Parquet类似,ORC的高级压缩也有效地降低了存储成本
- Avro:较低的压缩效率使得与Parquet和ORC相比存储成本更高
# Example of how to save data back to Google Cloud Storage in different formats
# Save DataFrame as Parque
parquet_df.write.parquet("gs://your-bucket/output_parquet")
# Save DataFrame as Avro
avro_df.write.format("avro").save("gs://your-bucket/output_avro")
# Save DataFrame as ORC
orc_df.write.orc("gs://your-bucket/output_orc")
- 数据处理成本
- 数据处理成本是基于在GCP上使用Dataproc执行各种查询所需的计算资源计算得出的。GCP对dataproc的使用收费是基于集群的大小以及资源使用的持续时间。
- 计算成本:
- Parquet和ORC:由于它们高效的列式存储,这些格式减少了读取和处理的数据量,从而降低了计算成本。更快的查询执行时间也为节约成本做出了贡献,尤其是对于涉及大数据集的复杂查询。
- Avro:由于Avro是基于行的格式,它需要更多的计算资源,这增加了读取和处理的数据量。这导致了更高的成本,特别是在读取密集型操作中。
结论
在大数据环境中,存储格式的选择对查询性能和成本有显著影响。上述研究和实验证明了以下关键点:
- Parquet 和 ORC:这些列式存储格式提供了优秀的压缩效果,从而降低了存储成本。它们只读取必要列的能力极大地提高了查询性能和减少了数据处理成本。由于其高级索引和优化特性,ORC在某些查询类型中略优于Parquet,使其成为既需要高读性能又需要高写性能的混合工作负载的理想选择。
- Avro:虽然Avro在压缩和查询性能方面不如Parquet和ORC高效,但在需要快速写操作和模式演化的用例中表现出色。这种格式非常适合涉及数据序列化和流式传输的场景,在这些场景中,写性能和灵活性被置于读效率之上。
- 成本效益:在像GCP这样的云环境中,成本与存储和使用计算资源紧密相关,选择正确的格式可以带来显著的成本节约。对于主要以读取为主的数据分析工作负载,Parquet和ORC是最具成本效益的选择。对于需要快速数据摄取和灵活模式管理的应用程序,尽管其存储和计算成本较高,Avro仍是一个合适的选择。
建议
根据我们的分析,我们建议如下:
- 对于以读取为主的分析工作负载:使用Parquet或ORC。这些格式由于其高压缩率和优化的查询性能,提供了卓越的性能和成本效益。
- 对于以写入为主的工作负载和序列化:使用Avro。它更适合快速写入和模式演化的关键场景,例如数据流处理和消息系统。
- 对于混合工作负载:ORC为读写操作提供了平衡的性能,使其成为数据负载变化的环境的理想选择。
总结
为大数据环境选择合适的存储格式对于优化性能和成本至关重要。了解每个格式的优势和劣势使数据工程师能够根据特定用例定制他们的数据架构,最大化效率和最小化成本。随着数据量的持续增长,对于存储格式的明智决策将越来越重要,以维护可扩展和成本效益高的数据解决方案。
通过仔细评估本文中提到的性能基准和成本影响,组织可以选择最适合其运营需求和财务目标的存储格式。
Source:
https://dzone.com/articles/performance-and-cost-implications-parquet-avro-orc