使用 Athena 查询 Apache Hudi 数据集 - Amazon Athena
AWS 文档中描述的 AWS 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅中国的 AWS 服务入门

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

使用 Athena 查询 Apache Hudi 数据集

Apache Hudi 是一种简化增量数据处理的开源数据管理框架。记录级别插入、更新、更新插入和删除操作会得到更精细的处理,从而减少开销。Upsert 是指将记录插入现有数据集(如果它们不存在)或更新记录(如果它们存在)的功能。

Hudi 处理数据插入和更新事件,而不会创建许多小文件来造成分析性能问题。Apache Hudi 会自动跟踪更改并合并文件,使其保持最佳大小。这样便无需构建可监控许多小文件并将其重写为较少大文件的自定义解决方案。

Hudi 数据集适用于以下使用案例:

由 Hudi 管理的数据集使用开放存储格式存储在 S3 中。目前,Athena 可以读取压缩的 Hudi 数据集,但不能写入 Hudi 数据。Athena 使用 Apache Hudi 版本 0.5.2-incubating,可能会发生变化。有关此 Hudi 版本的更多信息,请参阅 上的 apache/hudi 版本-0.5.2GitHub.com.

Hudi 数据集存储类型

Hudi 数据集可以是以下类型之一:

  • 写入时复制 (CoW) – 数据以列式格式存储 (Parquet),并且每次更新都会在写入过程中创建一个新版本的文件。

  • 读取时合并 (MoR) – 数据使用列式 (Parquet) 和基于行的 (Avro) 格式的组合进行存储。更新将记录到基于行的 delta 文件中,并根据需要压缩以创建列式文件的新版本。

对于 CoW 数据集,每次更新记录时,包含该记录的文件都会使用更新后的值进行重写。对于 MoR 数据集,每次进行更新时,Hudi 仅写入已更改记录的行。MoR 更适合读取量较少的写入或更改密集型工作负载。CoW 更适合更改频率较低但读取量繁重的工作负载。

Hudi 为访问数据提供三个逻辑视图:

  • 读取优化视图 – 提供来自 CoW 表的最新提交的数据集和来自 MoR 表的最新压缩数据集。

  • 增量视图 – 提供 CoW 数据集中两个操作之间的更改流,以馈送到下游作业以及提取、转换、加载 (ETL) 工作流程。

  • 实时视图 – 通过内联合并列式和基于行的文件,从 MoR 表提供最新提交的数据。

目前,Athena 仅支持其中的第一个视图:读取优化视图。对读取优化的视图的查询返回所有压缩数据,这将提供良好的性能,但不包含最新的增量提交。有关存储类型之间的权衡的更多信息,请参阅 Apache Hudi 文档中的存储类型和视图

注意事项和限制

  • Athena 仅支持读取 Hudi 数据的紧凑视图。

    • 对于写入时复制 (CoW),Athena 支持快照查询。

    • 对于读取时合并 (MoR),Athena 支持读取优化查询。

  • Athena 不支持对 Hudi 数据使用 CTASINSERT INTO。如果您希望 Athena 支持编写 Hudi 数据集,请将反馈发送到

    有关写入 Hudi 数据的更多信息,请参阅以下资源:

  • 不支持在 Athena 中的 Hudi 表上使用 MSCK REPAIR TABLE。如果您需要加载未在 AWS Glue 中创建的 Hudi 表,请使用 ALTER TABLE ADD PARTITION

Video

以下视频说明了如何使用 Amazon Athena 查询基于 Amazon S3 的数据湖中 Apache Hudi 数据集的读取优化视图。

创建 Hudi 表

本节提供 Athena 中用于 Hudi 数据的分区和非分区表的 CREATE TABLE 语句示例。

如果您已在 AWS Glue 中创建了 Hudi 表,则可以直接在 Athena 中查询它们。在 Athena 中创建 Hudi 表时,您必须先运行 ALTER TABLE ADD PARTITION 以加载 Hudi 数据,然后才能查询该数据。

写入时复制 (CoW) 创建表示例

未分区的 CoW 表

以下示例在 CoW 中创建未分区的 Athena 表。

CREATE EXTERNAL TABLE `non_partition_cow`( `_hoodie_commit_time` string, `_hoodie_commit_seqno` string, `_hoodie_record_key` string, `_hoodie_partition_path` string, `_hoodie_file_name` string, `event_id` string, `event_time` string, `event_name` string, `event_guests` int, `event_type` string) ROW FORMAT SERDE 'org.apache.hadoop.hive.ql.io.parquet.serde.ParquetHiveSerDe' STORED AS INPUTFORMAT 'org.apache.hudi.hadoop.HoodieParquetInputFormat' OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.parquet.MapredParquetOutputFormat' LOCATION 's3://bucket/folder/non_partition_cow'

分区 CoW 表

以下示例在 CoW 中创建分区的 Athena 表。

CREATE EXTERNAL TABLE `partition_cow`( `_hoodie_commit_time` string, `_hoodie_commit_seqno` string, `_hoodie_record_key` string, `_hoodie_partition_path` string, `_hoodie_file_name` string, `event_id` string, `event_time` string, `event_name` string, `event_guests` int) PARTITIONED BY ( `event_type` string) ROW FORMAT SERDE 'org.apache.hadoop.hive.ql.io.parquet.serde.ParquetHiveSerDe' STORED AS INPUTFORMAT 'org.apache.hudi.hadoop.HoodieParquetInputFormat' OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.parquet.MapredParquetOutputFormat' LOCATION 's3://bucket/folder/partition_cow'

以下 ALTER TABLE ADD PARTITION 示例将两个分区添加到示例 partition_cow 表中。

ALTER TABLE partition_cow ADD PARTITION (event_type = 'one') LOCATION 's3://bucket/folder/partition_cow/one/' PARTITION (event_type = 'two') LOCATION 's3://bucket/folder/partition_cow/two/'

读取时合并 (MoR) 创建表示例

Hudi 在 Hive 元存储中为 MoR 创建两个表:一个具有您指定的名称的表(即读取优化视图)和一个附加了 _rt(即实时视图)的同名表。但是,在 MoR 中创建 Athena 表时,您只能查询读取优化的视图。

读取时的未分区合并 (MoR) 表

以下示例在 MoR 中创建未分区的 Athena 表。

CREATE EXTERNAL TABLE `nonpartition_mor`( `_hoodie_commit_time` string, `_hoodie_commit_seqno` string, `_hoodie_record_key` string, `_hoodie_partition_path` string, `_hoodie_file_name` string, `event_id` string, `event_time` string, `event_name` string, `event_guests` int, `event_type` string) ROW FORMAT SERDE 'org.apache.hadoop.hive.ql.io.parquet.serde.ParquetHiveSerDe' STORED AS INPUTFORMAT 'org.apache.hudi.hadoop.HoodieParquetInputFormat' OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.parquet.MapredParquetOutputFormat' LOCATION 's3://bucket/folder/nonpartition_mor'

读取时的分区合并 (MoR) 表

以下示例在 MoR 中创建分区的 Athena 表。

CREATE EXTERNAL TABLE `partition_mor`( `_hoodie_commit_time` string, `_hoodie_commit_seqno` string, `_hoodie_record_key` string, `_hoodie_partition_path` string, `_hoodie_file_name` string, `event_id` string, `event_time` string, `event_name` string, `event_guests` int) PARTITIONED BY ( `event_type` string) ROW FORMAT SERDE 'org.apache.hadoop.hive.ql.io.parquet.serde.ParquetHiveSerDe' STORED AS INPUTFORMAT 'org.apache.hudi.hadoop.HoodieParquetInputFormat' OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.parquet.MapredParquetOutputFormat' LOCATION 's3://bucket/folder/partition_mor'

以下 ALTER TABLE ADD PARTITION 示例将两个分区添加到示例 partition_mor 表中。

ALTER TABLE partition_mor ADD PARTITION (event_type = 'one') LOCATION 's3://bucket/folder/partition_mor/one/' PARTITION (event_type = 'two') LOCATION 's3://bucket/folder/partition_mor/two/'

另请参阅

有关使用 AWS Glue 自定义连接器和 AWS Glue 2.0 作业创建您可以使用 Athena 查询的 Apache Hudi 表的信息,请参阅 AWS 大数据博客中的使用 AWS Glue 自定义连接器写入到 Apache Hudi 表