跳至内容

如何对 Amazon Athena 中的分区投影问题进行故障排除?

2 分钟阅读
0

我想对 Amazon Athena 中的分区投影问题进行故障排除。

简短描述

分区投影问题可能与将 storage.location.template 与 Amazon Simple Storage Service (Amazon S3) 目录结构相匹配有关。如果该列被定义为分区列,则它需要在 storage.location.template 中有一个位置以及该列的投影配置。当您创建 storage.location.template 时,分区值会投影到模板中,以提取数据的 Amazon S3 路径。如果模板与您的目录不匹配或投影配置缺失,则会出现问题。

根据以下场景对 Athena 中的分区投影问题进行故障排除:

  • 您的 Athena 表已经设置了分区投影,但是当您查询该表时没有结果。
  • 您的 Athena 表已设置分区投影,但您的查询失败并显示错误 INVALID_TABLE_PROPERTY: The 'storage.location.template' table property must contain templates for all partition columns!(INVALID_TABLE_PROPERTY:“storage.location.template”表属性必须包含所有分区列的模板!)
  • 您的 Athena 表已设置分区投影,但您的查询失败并显示错误 INVALID_TABLE_PROPERTY: Table (table-name) is configured for partition projection, but the following partition columns are missing projection configuration: (partition-column-name)(INVALID_TABLE_PROPERTY:表 (table-name) 已配置为分区投影,但以下分区列缺少投影配置:(partition-column-name))
  • 您的 Athena 表采用 Hive 式分区,但您希望使用分区投影来查询表,而不是加载分区。

解决方法

您的 Athena 表已设置分区投影,但是当您查询该表时没有结果

要对此场景进行故障排除,请执行以下操作:

设置分区投影并检查表参数。确保 projection.enabledtrue。对于表中的每个分区列,将 projection.columnName.type 设置为 enumintegerdateinjected

  • 如果投影类型为 date,则将列类型设置为 String。使用 String 作为分区键的日期类型。有关详细信息,请参阅 Amazon Athena 中的数据类型
  • 如果投影类型为 date,请使用 projection.columnName.rangeprojection.columnName.format。您的 projection.columnName.format 必须与 Amazon S3 路径上数据的配置方式相对应。另外,根据需要使用 projection.columnName.intervalprojection.columnName.range。有关详细信息,请参阅日期类型
  • 如果投影类型为 enum,请将 projection.columnName.values 设置为该分区列的所有潜在值的列表。
  • 如果投影类型为 integer,请将 projection.columnName.range 设置为该列的潜在值范围。另外,根据需要使用 projection.columnName.intervalprojection.columnName.digits。有关详细信息,请参阅整数类型
  • 对于 injected 类型的列,请确保您的查询具有筛选器表达式,例如每列的 WHERE <injected_col>。此外,在 injected 列的分区列定义中使用 String 列类型。

检查 storage.location.template 在每个分区列是否有占位符,以及是否与存储桶的 Amazon S3 目录结构相匹配。例如,AWS CloudTrail 日志可以使用分区投影。

**注意:**默认情况下,不会预测您的 AWS 区域和账户 ID。有关详细信息,请参阅使用分区投影在 Athena 中创建 CloudTrail 日志表

要使用 CloudTrail 日志投影区域和账户 ID,请使用以下模板。使用 enum 类型并确保枚举所有区域和账户 ID。

**注意:**将 example-bucket 替换为所需的 Amazon S3 存储桶。将投影您的 **region(区域)、timestamp(时间戳)**和 account(账户)字段:

'storage.location.template'='s3://<example-bucket>/AWSLogs/${account}/CloudTrail/${region}/${timestamp}'

要查询 Athena 表以查找特定 Amazon S3 路径中的数据,请运行以下命令:

**注意:**将 example-YYYY/MM/DD 替换为所需的时间戳,将 example-account-ID 替换为所需的账户 ID,将 example-region 替换为所需的区域。

SELECT * FROM cloudtrail_logs_pp WHERE timestamp='YYYY/MM/DD' AND account=example-account-ID AND region=example-region

分区示例:

s3://bucket/AWSLogs/example-account-ID/CloudTrail/example-region/YYYY/MM/DD

您的 Athena 表已设置分区投影,但您的查询失败并显示错误 INVALID_TABLE_PROPERTY: The 'storage.location.template' table property must contain templates for all partition columns!(INVALID_TABLE_PROPERTY:“storage.location.template”表属性必须包含所有分区列的模板!)

如果您收到此错误,则说明 storage.location.template 缺少分区列占位符。要解决问题,请确保 PARTITIONED BY 子句中的每列都有占位符。

您的 Athena 表已设置分区投影,但您的查询失败并显示错误 INVALID_TABLE_PROPERTY: Table (table-name) is configured for partition projection, but the following partition columns are missing projection configuration: (partition-column-name)(INVALID_TABLE_PROPERTY:表 (table-name) 已配置为分区投影,但以下分区列缺少投影配置:(partition-column-name))

如果您收到此错误,则说明由 PARTITIONED BY 子句定义的列缺少投影所需的表参数,例如 projection.columnName.format。要解决此问题,请按如下方式检查您的表参数:

  • 如果投影类型为 date,请使用 projection.columnName.rangeprojection.columnName.format。您的 projection.columnName.format 必须与 Amazon S3 路径上数据的配置方式相对应。另外,根据需要使用 projection.columnName.intervalprojection.columnName.range。有关详细信息,请参阅日期类型
  • 如果投影类型为 enum,请将 projection.columnName.values 设置为该分区列的所有潜在值的列表。
  • 如果投影类型为 integer,请将 projection.columnName.range 设置为该列的潜在值范围。另外,根据需要使用 projection.columnName.intervalprojection.columnName.digits。有关详细信息,请参阅整数类型
  • 对于 injected 类型的列,请确保您的查询中每个 injected 列都有筛选器表达式。此外,对于 injected 列,使用 PARTITIONED BY 子句中的 String 列类型。

您的 Athena 表采用 Hive 式分区,但您希望使用分区投影来查询表,而不是加载分区。

如果您的 Athena 表采用 Hive 式分区,但您希望使用分区投影,请检查存储模板和投影格式。存储模板和投影格式必须包含 Amazon S3 路径的 partition_col_name= 部分。运行以下命令:

**注意:**将 example-table-name 替换为所需表的名称。

CREATE EXTERNAL TABLE <example-table-name> (
col1 int,
col2 int
)
PARTITIONED BY
partition_col_name STRING
)
ROW FORMAT DELIMITED
LOCATION
's3://bucket/prefix/'
TBLPROPERTIES (
  'projection.enabled'='true',
  'projection.partition_col_name.type'='<enum,date,etc>',
  ... ##Omitting type-based projection parameters
  'storage.location.template'='s3://bucket/prefix/partition_col_name={partition_col_name}/')

如果您有多个 Hive 式分区,并且希望将它们映射到单个投影分区列,请更改列格式。要查询您的 Amazon S3 数据以获得名为 date 的单个分区列,请运行以下命令:

**注意:**将 example-table-name 替换为所需表的名称。

CREATE EXTERNAL TABLE <example-table-name> (col1 int, col2 int)
PARTITIONED BY (
`date` STRING
)
ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.OpenCSVSerde'
LOCATION "s3://bucket/prefix/"
TBLPROPERTIES (
  'projection.enabled'='true',
  'projection.date.type'='date',
  'projection.date.format'='\'year=\'yyyy/\'month=\'MM/\'day=\'dd',
  'projection.date.range'='year=2023/month=01/day=01,year=2023/month=12/day=31',
  'storage.location.template' = 's3://bucket/prefix/${date}/')

Amazon S3 路径示例:

s3://bucket/prefix/year=/month=/day=/
AWS 官方已更新 2 年前