利用排序与Z序压缩优化Amazon S3中Apache Iceberg查询性能

本文介绍了AWS新推出的排序与Z序压缩策略,用于优化Apache Iceberg在Amazon S3中的查询性能。通过重新组织数据布局,减少查询时扫描的文件数量,显著提升查询速度并降低计算成本,适用于大规模数据分析场景。

利用排序与Z序压缩优化Amazon S3中Apache Iceberg查询性能

您现在可以使用排序和Z序压缩来提升Apache Iceberg在Amazon S3 Tables和通用S3存储桶中的查询性能。Iceberg通常用于通过AWS Glue Data Catalog或S3 Tables管理Amazon Simple Storage Service (Amazon S3) 中的大规模分析数据集。Iceberg表支持并发流和批处理摄取、模式演进和时间旅行等用例。在处理高摄取或频繁更新的数据集时,数据湖可能会积累许多小文件,影响查询的成本和性能。您反馈说优化Iceberg数据布局操作复杂,通常需要开发和维护自定义管道。尽管默认的binpack策略与托管压缩提供了显著的性能改进,但为S3和S3 Tables引入排序和Z序压缩选项,为跨一个或多个维度的查询过滤带来了更大的增益。

两种新的压缩策略:排序和Z序

为了帮助更有效地组织数据,Amazon S3现在支持两种新的压缩策略:排序和Z序,以及默认的binpack压缩。这些高级策略通过AWS Glue Data Catalog优化,可用于完全托管的S3 Tables和通用S3存储桶中的Iceberg表。

排序压缩基于用户定义的列顺序组织文件。当您的表有定义的排序顺序时,S3 Tables压缩现在会在压缩过程中使用它来将相似的值聚类在一起。这通过减少扫描的文件数量来提高查询执行的效率。例如,如果您的表通过排序压缩按state和zip_code组织,那么在这些列上过滤的查询将扫描更少的文件,从而改善延迟并降低查询引擎成本。

Z序压缩通过启用跨多个维度的有效文件修剪更进一步。它将多个列的值的二进制表示交织成一个可以排序的单个标量,使得这种策略特别适用于空间或多维查询。例如,如果您的工作负载包括同时按pickup_location、dropoff_location和fare_amount过滤的查询,与传统的基于排序的布局相比,Z序压缩可以减少扫描的文件总数。

S3 Tables使用您的Iceberg表元数据来确定当前的排序顺序。如果表有定义的排序顺序,则无需额外配置即可激活排序压缩——它会在持续维护期间自动应用。要使用Z序,您需要使用S3 Tables API更新表维护配置,并将策略设置为z-order。对于通用S3存储桶中的Iceberg表,您可以通过更新压缩设置来配置AWS Glue Data Catalog在优化期间使用排序或Z序压缩。

实际应用示例

我将通过一个使用Apache Spark和AWS命令行界面(AWS CLI)的简化示例来演示。我安装了一个Spark集群和一个S3表存储桶。我在testnamespace中有一个名为testtable的表。我暂时禁用了压缩,以便向表中添加数据。

添加数据后,我检查表的文件结构。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
spark.sql("""
  SELECT 
    substring_index(file_path, '/', -1) as file_name,
    record_count,
    file_size_in_bytes,
    CAST(UNHEX(hex(lower_bounds[2])) AS STRING) as lower_bound_name,
    CAST(UNHEX(hex(upper_bounds[2])) AS STRING) as upper_bound_name
  FROM ice_catalog.testnamespace.testtable.files
  ORDER BY file_name
""").show(20, false)

输出显示表由多个小文件组成,新文件的上下界有重叠——数据显然未排序。

我设置表的排序顺序。

1
spark.sql("ALTER TABLE ice_catalog.testnamespace.testtable WRITE ORDERED BY name ASC")

我启用表压缩(默认启用;我在演示开始时禁用了它)。

1
aws s3tables put-table-maintenance-configuration --table-bucket-arn ${S3TABLE_BUCKET_ARN} --namespace testnamespace --name testtable --type icebergCompaction --value "status=enabled,settings={icebergCompaction={strategy=sort}}"

然后,我等待下一个压缩作业触发。这些作业全天运行,当有足够多的小文件时。我可以用以下命令检查压缩状态。

1
aws s3tables get-table-maintenance-job-status --table-bucket-arn ${S3TABLE_BUCKET_ARN} --namespace testnamespace --name testtable

压缩完成后,我再次检查组成表的文件。我看到数据被压缩为两个文件,上下界显示数据在这两个文件中已排序。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
spark.sql("""
  SELECT 
    substring_index(file_path, '/', -1) as file_name,
    record_count,
    file_size_in_bytes,
    CAST(UNHEX(hex(lower_bounds[2])) AS STRING) as lower_bound_name,
    CAST(UNHEX(hex(upper_bounds[2])) AS STRING) as upper_bound_name
  FROM ice_catalog.testnamespace.testtable.files
  ORDER BY file_name
""").show(20, false)

文件更少,大小更大,并且在指定的排序列上有更好的聚类。

要使用Z序,我遵循相同的步骤,但在维护配置中设置strategy=z-order。

区域可用性

排序和Z序压缩现在在所有支持Amazon S3 Tables的AWS区域以及支持AWS Glue Data Catalog优化的通用S3存储桶中可用。S3 Tables除现有使用和维护费用外,不收取额外费用。对于Data Catalog优化,压缩期间适用计算费用。

通过这些更改,在排序或Z序列上过滤的查询受益于更快的扫描时间和降低的引擎成本。根据我的经验,取决于数据布局和查询模式,我从binpack切换到排序或Z序时观察到性能提升三倍或更多。告诉我们您在实际数据上的增益是多少。

要了解更多,请访问Amazon S3 Tables产品页面或查看S3 Tables维护文档。您还可以立即使用S3 Tables API或AWS Glue优化开始在自己的表上测试新策略。

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计