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

Posted

技术标签:

【中文标题】Redshift Unload:仅在第一个分区中添加标头,不包括其余部分【英文标题】:Redshift Unload: Add headers only in first partition, excluding the rest 【发布时间】:2021-03-26 11:13:35 【问题描述】:

我正在将 redshift 表卸载到 S3,我只希望第一个分区包含 column headers,其他分区不应包含标题。

然而,

UNLOAD ('SELECT * FROM table') 
TO 's3://bucket/' 
FORMAT CSV 
IAM_ROLE arn:aws:iam::<AccNo>:role/myRedshiftRole' 
HEADER;`

在每个分区中添加标题。目前我正在执行两次查询(第一次有标题,然后没有标题),并删除不必要的分区。

还有比这更有效的方法吗?

【问题讨论】:

不要这么认为!创建文件后,您如何使用/处理文件? 【参考方案1】:

Redshift 为集群中的每个切片生成至少 1 个 S3 对象,然后当这些文件通过行限制时,将创建新对象。所以你看到没有“第一个”文件(对象或分区),它们都是相互平行的。 (是的,你可以去并行,但稍后会更多。)真正的问题是“你为什么想要这个?”。我预计,其他一些工具或过程或个人需要它,但真正的问题是“如何在从 Redshift 卸载后将列名传递给所述工具?”。我会更多地探讨这个问题,因为我希望它会为您打开解决方案的空间。

过去,我不得不为客户解决这个确切的问题(旧工具的要求,并不是真正的最佳方法)。 2 种方法:

    如果要卸载的数据相对较小,您可以使用“并行关闭”进行卸载。这会将卸载数据路由回领导节点,领导节点将在 S3 中写入单个对象(直到前面提到的行限制)。然后,不要卸载有问题的表,而是卸载列名的 UNION,并将表(或查询)中的数据转换为文本。在这种方法中可能会出现一些微妙的陷阱,随着数据变大会产生多个文件,并且效率不高,因为所有数据都必须通过领导节点进行路由。但这种方法是可行的。 生成一个仅包含标题信息的单独文件,并将其定义为下游进程要读取的“第一个”文件。这可以通过来自 Redshift 或其他一些进程/工具的单独卸载命令来完成。表(或查询)的卸载将保持不变,它预计会有多个文件,并且 Redshift 可以有效地生成对象(从计算节点并行)。这种方法比 #1 更合理、更安全。

正如我之前所说,您确实在处理一个不同的问题 - 如何定义存储在 S3 中的数据的 DDL?或者更广泛地说,如何一致地为在整个云环境中表示的数据定义 DDL?我也为这些问题构建了解决方案,我可以告诉您,从长远来看,解决这些问题将比试图使卸载数据看起来像 CSV 这样工具流能够工作提供更多价值。我确实理解现在需要让某些东西发挥作用,所以我希望这些建议对您有所帮助。

【讨论】:

我们使用旧系统,目前从 redshift 导入数据。它要求我们只为第一个文件(000 分区)提供列标题。目前我们使用的数据是 CSV 格式,但 Parquet 文件也将在以后使用。话虽如此,我真的很喜欢第二种方法,一定会尝试一下。谢谢

以上是关于Redshift Unload:仅在第一个分区中添加标头,不包括其余部分的主要内容,如果未能解决你的问题,请参考以下文章

为啥 Amazon Redshift UNLOAD 性能对于新数据要好得多?

以特定分区格式将数据卸载到 redshift

Redshift 中的 Unload 命令语法错误

UNLOAD 命令是不是从 redshift 中删除或删除数据?

Redshift UNLOAD 语句在 19 分钟后被取消

带有区分大小写的标头的 Redshift Unload