web-dev-qa-db-ja.com

RedShiftのテーブルを単一のCSVファイルにアンロードする方法は?

テーブルをAmazon RedShiftからMySQLに移行したいのですが、「アンロード」を使用すると、MySQLに直接インポートするのが難しい複数のデータファイルが生成されます。

MySQLに直接インポートできるように、テーブルを単一のCSVファイルにアンロードする方法はありますか?

19
ciphor

1つのファイルに送信するには、Parallel Offを使用します

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;
37

これは今のところ古い質問ですが、既存の回答はすべて少し誤解を招くように感じます。 「Redshiftが常にS3のSINGLEファイルにアンロードすることを100%保証できますか?」という質問の場合、答えは単純です[〜#〜]いいえ[〜#〜]

そうは言っても、ほとんどの場合、通常は1つのファイルで終わるような方法でクエリを制限できます。ドキュメント( 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のもう1つのいい副作用は、ORDER BY句がある場合はそれを尊重し、複数の出力ファイル間でも、すべてのレコードの順序を維持する順序でファイルを生成することです。

補遺:LIMIT 2147483647を使用してリーダーノードにすべての処理を強制し、単一の出力ファイルを生成することについて、いくつかの民間知識があるようですが、これは実際にはRedshiftのドキュメントのどこにも記載されていないようです。このような場合、いつでも変更される可能性があるため、これに依存することは悪い考えのようです。

9

これは少し回避策ですが、クエリをサブクエリにして制限を含める必要があります。その後、1つのファイルに出力します。例えば。

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

つまり、基本的には限られたセットからすべてを選択することになります。それが機能する唯一の方法です。 2147483647は、制限句が符号なし整数引数を取るため、最大制限です。

したがって、以下は1つのファイルにアンロードします。

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 ; 
3
davefender

いいえ。 { マニフェストを使用して、すべての出力を単一のファイルに送信するようにRedshiftに指示します。 }以前の回答は間違っていました。

単一のファイルを取得するには、2つの方法が考えられます。

  1. より簡単:実際の出力クエリの周りにSELECT…LIMITクエリをラップします これによりSO answer ですが、これは最大20億行に制限されています。
  2. 難しい: ファイルを結合するためにUnix catユーティリティを使用cat File1.txt File2.txt > union.txt。これには、まずS3からファイルをダウンロードする必要があります。
1
Joe Harris

確かに、Redshiftが単一の出力ファイルのみを生成するように強制する方法はありません。

標準のUNLOADでは、システムスライスの数と同じ数の出力ファイルが作成されます。つまり、8つのスライスを持つシステムでは、1つのアンロードコマンドに対して8つのファイルが作成されます(これが最も高速なアンロード方法です)。

アンロードコマンドにPARALLEL OFF句を追加すると、データ抽出sozeが6.25GBを超えないまで、出力が単一のファイルとして作成されます。その後、Redshiftが自動的にファイルを新しいチャンクに分割します。 。

圧縮された出力ファイルも生成する場合、同じことが当てはまります(もちろん、ファイルがより多くのレコードを収容できることを考慮すれば、単一の出力ファイルを生成する可能性が高くなります)。

1
Suvrat