Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/amazon-s3/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Amazon web services 在Athena CTA上创建100多个分区的替代方案_Amazon Web Services_Amazon S3_Amazon Athena - Fatal编程技术网

Amazon web services 在Athena CTA上创建100多个分区的替代方案

Amazon web services 在Athena CTA上创建100多个分区的替代方案,amazon-web-services,amazon-s3,amazon-athena,Amazon Web Services,Amazon S3,Amazon Athena,我目前正在根据AmazonS3中存储的信息创建一些新表。第一次使用AWS,今天我了解到AmazonAthena不能从CTAS查询创建超过100个分区 我正在使用sql进行转换,它工作得很好,但需要一种同时存储100多个分区的方法,以使过程更加可靠 我将分区设置为date,因此在4个月后,如果我需要通过sql重新创建表以加载大量数据(在sql中我进行了转换),我的进程将失败 您知道如何实现这一点吗?假设您希望使用CTAS查询处理4个月的数据,但需要按天对其进行分区。如果您在单个CTAS查询中执行此

我目前正在根据AmazonS3中存储的信息创建一些新表。第一次使用AWS,今天我了解到AmazonAthena不能从CTAS查询创建超过100个分区

我正在使用sql进行转换,它工作得很好,但需要一种同时存储100多个分区的方法,以使过程更加可靠

我将分区设置为date,因此在4个月后,如果我需要通过sql重新创建表以加载大量数据(在sql中我进行了转换),我的进程将失败


您知道如何实现这一点吗?

假设您希望使用CTAS查询处理4个月的数据,但需要按天对其进行分区。如果您在单个CTAS查询中执行此操作,您将得到大约4 x 30=120个分区,因此,正如您所提到的,查询将由于以下原因而失败

相反,您可以一次处理每个月的数据,这样就可以保证一次分区少于31个。但是,每个CTAS查询的结果应该在S3上有一个唯一的外部位置,即,如果您想在S3://bukcet name/data root下存储多个CTAS查询的结果,则需要在WITH子句下为外部位置中的每个查询扩展此路径。对于您的案例,最明显的选择是完整日期,例如:

s3://bukcet-name/data-root
├──2019-01            <-- external_location='s3://bukcet-name/data-root/2019-01'
|   └── month=01
|       ├── day=01
|       |   ...
|       └── day=31
├──2019-02            <-- external_location='s3://bukcet-name/data-root/2019-02'
|   └── month=02
|       ├── day=01
|       |   ...
|       └── day=28
...
你的电脑会复制到

s3://bukcet-name/data-root
├── month=01
|  ├── day=01
|  |   ...
|  └── day=31
├── month=02
|   ├── day=01
|   |   ...
|   └── day=28
使用AWS Glue数据目录进行操作。这有点复杂,但主要思想是定义一个根表,其位置指向s3://bukcet name/data root。然后在执行CTAS查询之后,您需要将有关分区的元信息从创建的暂存表复制到根表中。这一步将基于via,例如Python示例库。特别是,您将使用get\u分区和batch\u create\u分区方法

无论您选择哪种方法,您都需要使用某种作业调度软件,尤其是因为您的数据不仅仅是历史数据。我建议用这个。它可以被看作是Lambda函数和阶跃函数组合的替代,它是完全免费的。有很多博客文章和文档可以帮助你开始。例如:

s3://bukcet-name/data-root
├──2019-01            <-- external_location='s3://bukcet-name/data-root/2019-01'
|   └── month=01
|       ├── day=01
|       |   ...
|       └── day=31
├──2019-02            <-- external_location='s3://bukcet-name/data-root/2019-02'
|   └── month=02
|       ├── day=01
|       |   ...
|       └── day=28
...
:自动执行AWS Athena查询,并使用Airflow在S3周围移动结果。 完整的气流安装指南,以及 您甚至可以设置在查询以成功或失败状态终止时发送通知

要记住的事情: 一般来说,由于Athena是一个分布式系统,您无法明确控制CTAS查询将创建多少文件。另一方面,您不希望有很多小文件。因此,您可以尝试使用WITH子句中使用bucketed_by和bucket_count字段的方法

新建表格 具有 ... bucketed_by=数组['some_column_from_select'], 桶计数=1 像 -这是您的常规查询 选择 * 从…起 旧桌子;
或者,减少分区数量,即停止在月份级别。

最好的选择是为此任务编写一个Glue ETL spark作业,并使用spark sql执行所需的转换。这样,您仍然可以使用现有的sql查询

然后,您可以将处理后的输出写回某个S3路径。Spark允许您创建任意数量的分区。它还允许将新处理的数据附加到已处理的数据,只允许加载和转换新数据

完成ETL后,创建一个指向上述使用的S3路径和所需分区的外部表。这将是创建外部表的一个时间步骤。您只需要在每次粘合作业之后更新此外部表中的分区信息

总之,您需要执行以下操作:

创建要在Glue ETL上执行的spark脚本,该脚本将读取每日源数据,应用所需的转换,并将处理后的数据写入新分区中的S3。该脚本可以很容易地夯实,以接受日期作为输入,并且将是一次性活动

创建一个指向S3上已处理数据的外部表。这也是一次性活动

在每个粘合ETL作业之后,对上面的外部表执行MSCK Repair命令,以更新新分区

参考资料:


您是否特别需要在白天进行分区?你能改为按月分区吗?您的转换是在一天内执行的吗?最终表上的查询通常是按天过滤的,按天进行删除和重新生成似乎比按周或按月进行更容易,但我愿意接受建议。谢谢这只是历史数据,还是应该每天更新?@Ilykisil it每天更新一次/一天更新两次听起来很有趣,我试图避免使用更多的外部工具,因为我添加了更多的故障点。现在我有了NIFI用于提取和在雅典娜中进行转换,它变得更加棘手
监控管道的错误。谢谢我知道Airflow为监视和重置失败的任务提供了很好的UI,这是一个巨大的好处。它甚至有一个用于向Athena发送查询以及在S3上进行操作的接口。当我的ETL工作开始时,我开始使用它。我不得不监视谢谢你@harsh bafna,很抱歉延迟接受答案,我会使用胶水,你说得很好,我有一个小问题,只有一个问题,我可以像在Athena一样访问数组/结构吗?client.id或元素[1]。name我现在有一个错误,很难理解spark消息的页面。如果找不到,将生成另一个线程solution@Alejandro:此线程可能有助于: