将 Athena 与 AWS Glue 结合使用时的最佳实践 - Amazon Athena
AWS 文档中描述的 AWS 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅中国的 AWS 服务入门

如果我们为英文版本指南提供翻译,那么如果存在任何冲突,将以英文版本指南为准。在提供翻译时使用机器翻译。

将 Athena 与 AWS Glue 结合使用时的最佳实践

在将 Athena 与 AWS Glue 数据目录结合使用时,您可以使用 AWS Glue 来创建要在 Athena 中查询的数据库和表(架构),也可以使用 Athena 来创建架构,然后在 AWS Glue 和相关服务中使用它们。本主题提供了在使用上述任一方法时的注意事项和最佳实践。

在引擎盖下方, Athena 使用Presto处理DML声明,使用Hive处理创建和修改框架的DDL声明。借助这些技术,有几个可遵循的惯例,以使 Athena 和 AWS Glue 很好地协作。

本主题内容:

数据库、表和列名称

当您在 AWS Glue 中创建架构以便在 Athena 中进行查询时,请考虑以下事项:

  • 数据库名称不得超过 252 个字符。

  • 表名称不得超过 255 个字符。

  • 列名称不得超过 128 个字符。

  • 数据库名称、表名称和列名称仅可接受小写字母、数字和下划线字符。

您可以使用 AWS Glue 目录管理器来重命名列,但此时不能使用 AWS Glue 控制台更改表名称和数据库名称。要更正数据库名称,您需要创建一个新的数据库并将表复制到其中 (换言之,就是将元数据复制到新实体中)。对于表,您可以遵循类似的流程。您可以使用 AWS Glue SDK 或 AWS CLI 来完成此操作。

使用 AWS Glue 爬网程序

AWS Glue 爬网程序可帮助发现并注册 AWS Glue 数据目录中的数据集的架构。爬网程序会遍历您的数据,并检查其中的各个部分以确定架构。此外,爬网程序还可以检测并注册分区。更多信息,请参阅 使用爬虫器对数据进行编目AWS Glue 开发者指南.

安排爬网程序以保持 AWS Glue 数据目录和 Amazon S3 同步

AWS Glue 爬网程序可以设置为按计划或按需运行。更多信息,请参阅 工作和爬虫时间表AWS Glue 开发者指南.

如果您的数据在固定时间到达分区表,您可以设置 AWS Glue 爬网机按计划运行,以检测和更新表分区。这样可以消除长时间运行和昂贵运行的需求 MSCK REPAIR 命令或手动运行 ALTER TABLE ADD PARTITION 命令。更多信息,请参阅 表分区AWS Glue 开发者指南.

将多个数据源和爬网程序一起使用

当 AWS Glue 爬网扫描 Amazon S3 并检测多个目录,它使用启发式来确定表的根目录在目录结构中的位置,以及哪些目录是表的分区。在某些情况下,如果在两个或更多目录中检测到的架构相似,则爬网程序可能将它们视为分区而不是单独的表。一种帮助爬网程序发现单个表的方法是将每个表的根目录添加为爬网程序的数据存储。

以下示例是 Amazon S3 中的分区:

s3://bucket01/folder1/table1/partition1/file.txt s3://bucket01/folder1/table1/partition2/file.txt s3://bucket01/folder1/table1/partition3/file.txt s3://bucket01/folder1/table2/partition4/file.txt s3://bucket01/folder1/table2/partition5/file.txt

如果 table1table2 的架构类似,并且单个数据源在 AWS Glue 中设置为 s3://bucket01/folder1/,则爬网程序可能创建一个具有两个分区列的表:一个分区列包含 table1table2,另一个分区列包含 partition1partition5

要让 AWS Glue 爬网程序创建两个单独的表,请将爬网程序设置为具有两个数据源 s3://bucket01/folder1/table1/s3://bucket01/folder1/table2,如以下过程所示。

向 AWS Glue 中的现有爬网程序中添加另一个数据存储

  1. 登录 AWS 管理控制台并通过以下网址打开 AWS Glue 控制台:https://console.amazonaws.cn/glue/

  2. 选择 Crawlers (爬网程序),选择您的爬网程序,然后选择 Action (操作)Edit crawler (编辑爬网程序)

  3. Add information about your crawler 下,根据需要选择附加设置,然后选择 Next

  4. Add a data store 下,将 Include path 更改为表级别目录。例如,根据上述示例,您将从 s3://bucket01/folder1 to s3://bucket01/folder1/table1/。选择 下一步.

  5. 对于 Add another data store,选择 YesNext

  6. 对于 Include path (包含路径),输入您的其他表级别目录(例如,s3://bucket01/folder1/table2/),然后选择 Next (下一步)

    1. 对任何其他表级别目录重复步骤 3-5,并完成爬网程序配置。

Include locations (包含位置) 的新值显示在数据存储下,如下所示:

同步分区架构以避免“HIVE_PARTITION_SCHEMA_MISMATCH”

对 AWS Glue 数据目录中每个具有分区列的表,架构都在表级别并且针对表中的每个单独分区存储。分区的架构由 AWS Glue 爬网程序根据它在分区中读取的数据样本进行填充。有关更多信息,请参阅将多个数据源与爬网程序一起使用

当 Athena 运行查询时,它会验证表的架构和查询所需的任何分区的架构。验证会将列数据类型按顺序进行比较,确保它们对于重叠的列匹配。这可防止意外的操作,例如在表的中间添加或删除列。如果 Athena 检测到分区的架构与表的架构不同,则 Athena 可能无法处理查询,会因 HIVE_PARTITION_SCHEMA_MISMATCH 而失败。

可通过几种方式解决此问题。首先,如果意外添加了数据,您可以删除导致架构差异的数据文件,删除该分区,然后重新爬取数据。其次,您可以删除单个分区,然后在 Athena 中运行 MSCK REPAIR,以使用表的架构重新创建分区。只有当您确信应用的架构将继续正确读取数据时,此第二个选项才有效。

更新表元数据

在爬取之后,AWS Glue 爬网程序会自动分配某些表元数据,以帮助它与其他外部技术(如 Apache Hive、Presto 和 Spark)兼容。有时,爬网程序可能会错误地分配元数据属性。在使用 Athena 查询表之前,手动更正 AWS Glue 中的属性。更多信息,请参阅 查看和编辑表格详细信息AWS Glue 开发者指南.

当 CSV 文件将每个数据字段都用引号引起来,使 serializationLib 属性错误时,AWS Glue 可能会错误分配元数据。有关更多信息,请参阅用引号引起来的 CSV 数据

使用 CSV 文件

CSV 文件有时会将每个列所适用的数据值用引号引起来,并且 CSV 文件中可能包含标题值,而这不是要分析的数据的一部分。当您使用 AWS Glue 从这些文件创建架构时,请遵循本部分中的指导。

用引号引起来的 CSV 数据

您可能有一个CSV文件,其中包含包含双引号(如以下示例)的数据文件:

"John","Doe","123-555-1231","John said \"hello\"" "Jane","Doe","123-555-9876","Jane said \"hello\""

要运行查询 Athena 在由具有引用值的CSV文件创建的表上,您必须修改表属性 AWS Glue 使用OpenCSVSerDe。有关 OpenCSV SerDe 的更多信息,请参阅 用于处理 CSV 的 OpenCSVSerDe

在中编辑表格属性 AWS Glue 话务台

  1. 在 AWS Glue 控制台导航窗格,选择 桌子.

  2. 选择您要编辑的表,然后选择 编辑表格.

  3. 编辑表格详细信息 对话框,进行以下更改:

    • 对于 Serde序列化,输入 org.apache.hadoop.hive.serde2.OpenCSVSerde.

    • 对于 血清参数,在键中输入以下值 escapeChar, quoteChar、和 separatorChar:

      • 对于 escapeChar,输入反斜线(\)。

      • 对于 quoteChar,输入双引号(")。

      • 对于 separatorChar,输入逗号(,)。

更多信息,请参阅 查看和编辑表格详细信息AWS Glue 开发者指南.

更新 AWS Glue 编程的表属性

您可以使用 AWS Glue 更新表 API操作或 更新表 用于修改 SerDeInfo 表定义中的块,如以下示例所述。

"SerDeInfo": { "name": "", "serializationLib": "org.apache.hadoop.hive.serde2.OpenCSVSerde", "parameters": { "separatorChar": "," "quoteChar": "\"" "escapeChar": "\\" } },

具有标题的 CSV 文件

当您在 Athena 有 CREATE TABLE 你可以使用 skip.header.line.count 表格属性忽略CSV数据中的标题,如以下示例所示。

... STORED AS TEXTFILE LOCATION 's3://my_bucket/csvdata_folder/'; TBLPROPERTIES ("skip.header.line.count"="1")

或者,您可以事先删除CSV标题,以便不在 Athena 查询结果。实现此操作的一种方法是使用 AWS Glue 任务,它执行提取、转换和加载 (ETL) 工作。您可以使用 PySpark Python 方言的扩展语言在 AWS Glue 中编写脚本。更多信息,请参阅 写胶水中的职位AWS Glue 开发者指南.

以下示例显示 AWS Glue 脚本中的一个函数,它使用 from_options 写出动态帧,并将 writeHeader 格式选项设置为 false,从而删除标题信息:

glueContext.write_dynamic_frame.from_options(frame = applymapping1, connection_type = "s3", connection_options = {"path": "s3://MYBUCKET/MYTABLEDATA/"}, format = "csv", format_options = {"writeHeader": False}, transformation_ctx = "datasink2")

使用地理空间数据

AWS Glue 不内在支持已知文本 (WKT)、已知二进制 (WKB) 或其他 PostGIS 数据类型。AWS Glue 分类器解析地理空间数据并使用相应格式支持的数据类型对其进行分类,例如用于 CSV 的 varchar。与其他 AWS Glue 表一样,您可能需要更新从地理空间数据创建的表的属性,以允许 Athena 按原样解析这些数据类型。有关更多信息,请参阅 使用 AWS Glue 爬网程序使用 CSV 文件。Athena 可能无法按原样解析 AWS Glue 表中的某些地理空间数据类型。有关在 Athena 中使用地理空间数据的更多信息,请参阅查询地理空间数据

将针对 ETL 的 AWS Glue 任务与 Athena 一起使用

AWS Glue 任务执行 ETL 操作。AWS Glue 任务运行一个从源中提取数据、转换数据并将其加载到目标中的脚本。更多信息,请参阅 写胶水中的职位AWS Glue 开发者指南.

将 Athena 用于 AWS Glue ETL 任务来创建表

您在 Athena 中创建的表必须添加有名为 classification 的表属性,该属性标识数据的格式。这使 AWS Glue 能够将这些表用于 ETL 任务。分类值可以是 csv, parquet, orc, avro,或 json。示例 CREATE TABLE 陈述 Athena 如下:

CREATE EXTERNAL TABLE sampleTable ( column1 INT, column2 INT ) STORED AS PARQUET TBLPROPERTIES ( 'classification'='parquet')

如果在创建表时未添加表属性,则可以使用 AWS Glue 控制台添加它。

使用控制台更改分类属性

  1. 选择 Edit Table
  2. 对于 Classification,选择文件类型,然后选择 Apply

更多信息,请参阅 处理桌子AWS Glue 开发者指南.

使用 ETL 任务优化查询性能

AWS Glue 任务可帮助您将数据转换为一种可优化 Athena 中的查询性能的格式。数据格式会极大影响 Athena 中的查询性能和查询成本。

我们建议使用 Parquet 和 ORC 数据格式。AWS Glue 支持写入到这两种数据格式,从而使您可以更方便快捷地将数据转换为对 Athena 最佳的格式。有关这些格式的更多信息以及提高性能的其他方法,请参阅 Amazon Athena 的最佳性能调整技巧

当转换为 ORC 时将 SMALLINT 和 TINYINT 数据类型转换为 INT

要减少 Athena 无法读取 AWS Glue ETL 任务生成的 SMALLINTTINYINT 数据类型的可能性,请在使用向导或为 ETL 编写脚本时,将 SMALLINTTINYINT 转换为 INT

自动化针对 ETL 的 AWS Glue 任务

您可以将 AWS Glue ETL 任务配置为基于触发器自动运行。当来自外部 AWS 的数据被以次优格式推送到 Amazon S3 存储桶,以用于在 Athena 中查询时,此功能非常适用。更多信息,请参阅 触发AWGlue工作AWS Glue 开发者指南.