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

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

使用 Athena 查询阿帕奇胡迪数据集

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

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

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

Hudi 管理的数据集使用开放存储格式存储在 S3 中。目前,Athena 可以读取压缩的胡迪数据集,但不能写胡迪数据。Athena 使用阿帕奇胡迪版0.8.0,可能会发生变化。有关此 Hudi 版本的更多信息,请参阅0.8.0 版本(文档)在阿帕奇网站上。

Hudi 数据集Table类型

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

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

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

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

Hudi 提供三个查询类型用于访问数据:

  • 快照查询— 查看截至给定提交或压缩操作时表的最新快照的查询。对于 MOR 表,快照查询通过在查询时合并最新文件切片的基本文件和增量文件来显示表的最新状态。

  • 增量查询— 自给定的提交/压缩以来,查询只能看到写入表的新数据。这有效地提供了更改流以启用增量数据管道。

  • 读取优化查询— 对于 MOR 表,查询将看到最新压缩的数据。对于 CoW 表,查询将看到提交的最新数据。

下表显示了每种表类型的可能的 Hudi 查询类型。

表类型 可能的 Hudi 查询类型
写入时复制 快照,增量
读取时合并 快照,增量,读取优化

目前,Athena 支持快照查询和读取优化查询,但不支持增量查询。在 MOR 表上,所有数据暴露于读取优化查询是压缩。这提供了良好的性能,但不包括最新的增量提交。Snapshot 查询包含最新的数据但产生一些计算开销,这使得这些查询的性能降低。

有关表类型与查询类型之间的权衡的更多信息,请参阅表类型与查询在 Apache Hudi 文档中。

胡地术语变化:视图现在是查询

从发行版 0.5.1 开始,阿帕奇胡迪改变了一些术语。以前的视图在更高版本中被称为查询。下表总结了旧术语与新术语之间的变更。

旧术语 新术语

CoW:读取优化视图

MOR:实时视图

快照查询

增量视图 增量查询
MOR 读取优化视图 读取优化查询

引导操作中的表

从 Apache Hudi 版本 0.6.0 开始,引导操作功能可提供更好的现有镶木地板数据集的性能。引导操作只能生成元数据,使数据集保持原位,而不是重写数据集。

您可以使用 Athena 从引导操作中查询表,就像基于 Amazon S3 中数据的其他表一样。在您的CREATE TABLE语句中指定 Hudi 表路径,请在LOCATION子句。

有关在 Amazon EMR 中使用引导操作创建 Hudi 表的更多信息,请参阅来自阿帕奇胡迪的新功能在亚马逊 EMR 上市中的Amazon大数据博客。

注意事项和限制

Video

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

创建 Hudi 表

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

如果您有 Hudi 表已在Amazon Glue,您可以直接在 Athena 中查询它们。在您创建分区胡迪表在 Athena,你必须运行ALTER TABLE ADD PARTITION加载 Hudi 数据,然后才能查询它。

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

未分区 CoW 表

以下示例用 Athena 格式创建一个未分区的 CoW 表。

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 表

以下示例用 Athena 格式创建一个分区 CoW 表。

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 在元仓中为 MOR 创建两个表:一个用于快照查询的表,一个用于读取优化查询的表。两个表都可以查询。在 0.5.1 之前的 Hudi 版本中,用于读优化查询的表具有您在创建表时指定的名称。从胡迪版本 0.5.1 开始,表名后缀为_ro默认情况下。用于快照查询的表的名称是指定的名称,该名称附加了_rt

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

以下示例用 Athena 格式创建一个未分区的 MOR 表用于读取优化查询。请注意,读取优化查询使用输入格式HoodieParquetInputFormat

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'

以下示例用 Aquet 格式创建一个未分区 MOR 表,用 Parquet 格式进行快照查询。对于快照查询,请使用输入格式HoodieParquetRealtimeInputFormat

CREATE EXTERNAL TABLE `nonpartition_mor_rt`( `_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.realtime.HoodieParquetRealtimeInputFormat' OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.parquet.MapredParquetOutputFormat' LOCATION 's3://bucket/folder/nonpartition_mor'

读取时分区合并 (MOR) 表

以下示例在 Athena 中为读取优化查询创建分区的 MOR 表。

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/'

以下示例在 Athena 中为快照查询创建一个分区的 MOR 表。

CREATE EXTERNAL TABLE `partition_mor_rt`( `_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.realtime.HoodieParquetRealtimeInputFormat' OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.parquet.MapredParquetOutputFormat' LOCATION 's3://bucket/folder/partition_mor'

同样,以下ALTER TABLE ADD PARTITION示例将两个分区添加到示例partition_mor_rt表。

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

另请参阅

有关使用Amazon Glue自定义连接器和Amazon Glue2.0 作业来创建可以使用 Athena 查询的 Apache Hudi 表,请参阅写入阿帕奇胡迪表使用Amazon Glue自定义连接器中的Amazon大数据博客。