【问题标题】:How to unload a table on RedShift to a single CSV file?如何将 RedShift 上的表格卸载到单个 CSV 文件?
【发布时间】:2013-12-17 21:39:55
【问题描述】:

我想将一个表从 Amazon RedShift 迁移到 MySQL,但是使用“卸载”会生成多个难以直接导入 MySQL 的数据文件。

有没有办法将表卸载到单个 CSV 文件中,以便我可以直接将其导入 MySQL?

【问题讨论】:

  • 我对@9​​87654321@ 的回答应该适合你

标签: mysql amazon-web-services amazon-redshift


【解决方案1】:

当然,没有办法强制 Redshift 只生成一个输出文件。

在标准 UNLOAD 下,您将创建与系统切片数量相等的输出文件,即具有 8 个切片的系统将为单个卸载命令创建 8 个文件(这是最快的卸载方法。)

如果您在卸载命令中添加子句 PARALLEL OFF,您的输出将创建为单个文件,直到数据提取大小不超过 6.25GB,之后 Redshift 会自动将文件拆分为一个新的块。

如果您也生成压缩的输出文件,情况也是如此(当然,考虑到您的文件可以容纳更多的记录,您将有更大的机会生成单个输出文件。)。

【讨论】:

    【解决方案2】:

    在这一点上这是一个老问题,但我觉得所有现有的答案都有点误导。如果您的问题是“我可以绝对 100% 保证 Redshift 将始终卸载到 S3 中的单个文件吗?”,答案很简单

    话虽如此,在大多数情况下,您通常可以限制查询,使您最终得到一个文件。根据文档 (https://docs.aws.amazon.com/redshift/latest/dg/r_UNLOAD.html),限制生成的文件数量的主要因素是导出的实际原始大小(以字节为单位)(不是行数)。 Redshift UNLOAD 命令生成的输出文件大小限制为 6.2GB。

    因此,如果您想确保从 UNLOAD 获得单个输出文件,您应该尝试以下方法:

    • 指定PARALLEL OFF。 Parallel 默认为“ON”,通常会写入多个文件,除非您有一个很小的集群(设置“PARALLEL ON”的输出文件的数量与集群中的切片数量成正比)。 PARALLEL OFF 会将文件串行写入 S3 而不是并行写入,并且只有在超出大小限制时才会溢出到使用多个文件。
    • 限制输出的大小。如果您需要单个文件,则数据的原始大小必须小于 6.2GB。因此,您需要使您的查询具有更严格的WHERE 子句或使用LIMIT 子句来减少记录数。不幸的是,这些技术都不是完美的,因为行可以是可变大小的。我也不清楚GZIP 选项是否会影响输出文件大小溢出限制(不清楚 6.2GB 是 GZIP 之前的大小限制还是 GZIP 之后的大小限制)。

    对我来说,在大多数情况下最终生成单个 CSV 文件的 UNLOAD 命令是:

    UNLOAD
    ('SELECT <fields> FROM <table> WHERE <restrict_query>')
    TO 's3://<bucket_name>/<filename_prefix>'
    CREDENTIALS 'aws_access_key_id=<access_key>;aws_secret_access_key=<secret_key>'
    DELIMITER AS ','
    ADDQUOTES
    NULL AS ''
    PARALLEL OFF;
    

    PARALLEL OFF 的另一个不错的副作用是,它会尊重您的 ORDER BY 子句,如果您有一个子句,并按照使所有记录保持有序的顺序生成文件,即使跨多个输出文件也是如此。

    附录:似乎有一些关于使用 LIMIT 2147483647 强制领导节点进行所有处理并生成单个输出文件的民间知识,但这似乎并没有在 Redshift 文档的任何地方实际记录,并且因此,依赖它似乎是个坏主意,因为它随时可能发生变化。

    【讨论】:

    • 我有一个稍微脱离上下文的问题。转移到 s3 存储桶是从 Redshift 中获取数据的唯一方法吗?或者是否可以进行数据传输,例如从 Amazon redshift 到 Amazonelasticsearch 服务?
    • 我不相信有任何从 Redshift 到其他非 S3 服务的直接导出方法。话虽如此,您可以使用 AWS Data Pipeline 等工具来创建工作流以在服务之间传输数据,但您可能需要做一些额外的工作。
    • 感谢您的回复。在这个链接link 中,它说只有四个没有 Amazon elasticsearch 的数据源之间可以进行数据传输。
    【解决方案3】:

    为了发送到单个文件,请使用并行关闭

    unload ('select * from venue')
    to 's3://mybucket/tickit/unload/venue_' credentials 
    'aws_access_key_id=<access-key-id>;aws_secret_access_key=<secret-access-key>'
    parallel off;
    

    我还建议使用 Gzip,以使下载的文件更小。

    unload ('select * from venue')
    to 's3://mybucket/tickit/unload/venue_' credentials 
    'aws_access_key_id=<access-key-id>;aws_secret_access_key=<secret-access-key>'
    parallel off
    gzip;
    

    【讨论】:

    【解决方案4】:

    不。 {你可以use a manifest and tell Redshift to direct all output to a single file.} 以前的答案是错误的,我使用清单进行加载而不是卸载。

    似乎有两种可能的方式来获取单个文件:

    1. 更简单:围绕您的实际输出查询 as per this SO answer 包装一个 SELECT ... LIMIT 查询,但这仅限于约 20 亿行。
    2. 更难:Use the Unix cat utility to join the files togethercat File1.txt File2.txt &gt; union.txt。这将要求您首先从 S3 下载文件。

    【讨论】:

    • 你试过这个吗?清单似乎是由卸载产生的。
    • 抱歉,根据您的评论,它不适用于卸载。用两种可行的方法更新了答案。
    【解决方案5】:

    这是一种解决方法,但您需要将查询设为子查询并包含限制。然后它将输出到一个文件。例如

    select * from (select * from bizdata LIMIT 2147483647);
    

    所以基本上你是从有限的集合中选择所有的。这是它工作的唯一方式。 2147483647 是您的最大限制,因为限制子句采用无符号整数参数。

    所以以下内容将卸载到一个文件中:

    unload(' select * from (
    select bizid, data
    from biztable
    limit 2147483647);
     ') to 's3://.......' CREDENTIALS 'aws_access_key_id=<<aws_access_key_id>>;aws_secret_access_key=<<aws_secret_access_key>>' csv ; 
    

    【讨论】:

      猜你喜欢
      • 2018-03-22
      • 1970-01-01
      • 2017-01-08
      • 1970-01-01
      • 2018-09-07
      • 2018-07-18
      • 2020-02-11
      • 2013-08-12
      • 1970-01-01
      相关资源
      最近更新 更多