Redshift:可以在对 S3 进行分区卸载时为路径指定后缀吗?

Posted

技术标签:

【中文标题】Redshift:可以在对 S3 进行分区卸载时为路径指定后缀吗?【英文标题】:Redshift: Possibility to specify suffix for paths when doing PARTITIONED UNLOAD to S3? 【发布时间】:2020-06-26 14:06:04 【问题描述】:

在对 S3 进行分区卸载时,有什么方法可以为路径提供后缀?

例如如果我想将 +several+ 查询的输出用于批处理作业,其中查询输出按日期分区。

目前我在 S3 中有一个结构,例如:

s3://bucket/path/queryA/key=1/ *.parquet
s3://bucket/path/queryA/key=2/ *.parquet
s3://bucket/path/queryB/key=1/ *.parquet
s3://bucket/path/queryB/key=2/ *.parquet

但理想情况下,我希望:

s3://bucket/path/key=1/queryA/ *.parquet
s3://bucket/path/key=2/queryA/ *.parquet
s3://bucket/path/key=1/queryB/ *.parquet
s3://bucket/path/key=2/queryB/ *.parquet

这样我就可以将其用作批处理作业的输入路径(例如在 Sagemaker 上!):

s3://bucket/path/key=1/
s3://bucket/path/key=2/

这样每个批处理作业都具有批处理作业正在计算的特定日期的所有查询的输出。

目前,我在卸载后重新调整 S3 中的数据,但如果我可以为 Redshift 指定一个后缀以附加到 S3 卸载路径,+after+ 分区后缀,将会更快、更方便。

根据 UNLOAD 文档,我假设这是不可能的,我无法在 AWS 论坛上发帖。

但也许我可以使用其他一些命令或连接变量、涉及第二个分区键的字面值之类的破解,或者完全不同的策略?

【问题讨论】:

请发布您尝试过的 UNLOAD 查询示例以及 S3 中的输出。 听起来您正在尝试将固定字符串放在分区下方的键路径中。我不相信这可以做到。您可能会更幸运地生成清单并将其处理以输入到 SageMaker 【参考方案1】:

您可以添加 人工q 来标记查询,然后将其用作第二个分区 - 这将有效地为您的路径添加 q=queryA 前缀。

但是,redshift 不允许将UNLOAD 放入非空位置,除非您提供ALLOWOVERWRITE 选项。

然后,由于您不控制卸载的文件名(它们将取决于切片计数和最大文件大小),如果您碰巧具有相同的分区键,则允许覆盖可能会导致您的数据真正被覆盖。

要解决此问题,您可以再添加一个 人工 分区列,该列将向您的路径添加一个唯一组件(每次卸载的值相同)。为此,我在示例中使用了RANDOM - 您可以使用更冲突安全的东西。

下面是一个示例查询,它卸载数据而不覆盖结果,即使卸载多次。我针对不同的 partq 值运行它。

unload ($$

    WITH
    rand(rand) as (select md5(random())),
    input(val, part) as (
        select 1, 'p1' union all
        select 1, 'p2'
    )
    SELECT
        val,
        part,
        'queryB' as q,
        rand as r
    FROM input, rand

    $$)
TO 's3://XXX/partitioned_unload/'
IAM_ROLE 'XXX'
PARTITION by (part, q, r)
ALLOWOVERWRITE

这些是 3 次运行产生的文件:

aws s3 ls s3://XXX/partitioned_unload/ --recursive
2020-06-29 08:29:14          2 partitioned_unload/part=p1/q=queryA/r=b43e3ff9b6b271387e2ca5424c310bb5/0001_part_00
2020-06-29 08:28:58          2 partitioned_unload/part=p1/q=queryA/r=cfcd208495d565ef66e7dff9f98764da/0001_part_00
2020-06-29 08:29:54          2 partitioned_unload/part=p1/q=queryB/r=24a4976a535a584dabdf8861548772d4/0001_part_00
2020-06-29 08:29:54          2 partitioned_unload/part=p2/q=queryB/r=24a4976a535a584dabdf8861548772d4/0001_part_00
2020-06-29 08:29:14          2 partitioned_unload/part=p3/q=queryA/r=b43e3ff9b6b271387e2ca5424c310bb5/0002_part_00
2020-06-29 08:28:58          2 partitioned_unload/part=p3/q=queryA/r=cfcd208495d565ef66e7dff9f98764da/0001_part_00

【讨论】:

以上是关于Redshift:可以在对 S3 进行分区卸载时为路径指定后缀吗?的主要内容,如果未能解决你的问题,请参考以下文章

Amazon Redshift - 卸载到 S3 - 动态 S3 文件名

Redshift Unload:仅在第一个分区中添加标头,不包括其余部分

AWS Redshift - 在卸载到 s3 时设置零件大小

将空表从 redshift 卸载到 s3 的行为如何?

如何使用 aws unload 命令将数据从 AWS Redshift 卸载到 s3?

从 Redshift 卸载到 S3 时 JDBC 连接丢失。应该发生啥?