23

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

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

4

5 回答 5

44

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

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;
于 2014-06-24T14:37:40.493 回答
15

在这一点上这是一个老问题,但我觉得所有现有的答案都有点误导。如果您的问题是“我可以绝对 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 文档中的任何地方实际记录,因此依赖它似乎是个坏主意,因为它随时可能改变。

于 2015-06-24T17:04:48.943 回答
4

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

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 ; 
于 2013-12-05T14:19:38.950 回答
3

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

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

如果在 Unload Command 中添加子句 PARALLEL OFF,您的输出将创建为单个文件,直到数据提取 soze 不超过 6.25GB,之后 Redshift 会自动将文件分成一个新块.

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

于 2015-09-25T14:15:29.593 回答
2

没有。{ 您可以使用清单并告诉 Redshift 将所有输出定向到单个文件。以前的答案是错误的,我使用清单进行加载但没有卸载。

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

  1. 更简单:根据这个 SO 答案,围绕您的实际输出查询包装一个 SELECT ... LIMIT 查询,但这仅限于约 20 亿行。
  2. 更难:使用 Unixcat实用程序将文件连接在一起 cat File1.txt File2.txt > union.txt。这将要求您首先从 S3 下载文件。
于 2013-12-04T09:28:53.723 回答