RedshiftにParquetファイルをCOPYしたい場合、S3バケットのリージョンに注意が必要です
データ・アナリティクス事業本部の森脇です。
RedshiftのCOPYコマンドを使うと、S3からファイルをRedshiftにロードすることが可能です。
また、COPYコマンドオプションの「REGION」にてS3のリージョンを指定することで、S3とRedshiftのリージョンが異なる場合にもファイルをロードすることが可能です。
ただし、Parquetファイルはリージョンが異なる場合ロードできません。
実際に試してみましょう。
OKパターン(同一リージョンでのCOPY)
まずは同一リージョンでのCOPYを試します。
東京リージョン(ap-northeast-1)にRedshift, S3をそれぞれ作成します。
そして、S3バケットにデータファイルをアップロードします。
今回はcsv, parquetの両パターンを試してみます。
ファイルの中身はなんでもいいため、2列5行の適当なデータをpythonで作成しました。
csv:
python3.7 -c "print('c1,c2');[print(f'{i},{chr(i+65)}') for i in range(5)]" >./sample.csv
parquet:
python3.7 -c "import pandas as pd;pd.read_csv('./sample.csv').to_parquet('./sample.parquet')"
上記で作成したファイルを以下のようにS3にアップロードしました。
aws s3 ls --recursive s3://copy-test-ap-northeast-1 2021-01-12 10:55:51 26 copy/sample.csv 2021-01-12 10:55:40 2196 copy/sample.parquet
Redshiftにpsqlで接続し、COPY文を実行してみます。
psqlで接続し、器のテーブルを作成:
PGPASSWORD="password" psql -h test-redshift.abcdefg.ap-northeast-1.redshift.amazonaws.com -p 5439 -d testdb -U testuser testdb=# CREATE TABLE public.copy_test ( c1 BIGINT, c2 CHAR(1)); CREATE TABLE
csvのCOPY:
testdb=# COPY public.copy_test FROM 's3://copy-test-ap-northeast-1/copy/sample.csv' IAM_ROLE 'arn:aws:iam::1234567890:role/moriwaki-redshift-test-role' CSV IGNOREHEADER 1; INFO: Load into table 'copy_test' completed, 5 record(s) loaded successfully. COPY
parquetのCOPY:
testdb=# COPY public.copy_test FROM 's3://copy-test-ap-northeast-1/copy/sample.parquet' IAM_ROLE 'arn:aws:iam::1234567890:role/moriwaki-redshift-test-role' PARQUET; INFO: Load into table 'copy_test' completed, 5 record(s) loaded successfully. COPY
csv, parquetともうまくいきました。
NGパターン(クロスリージョンでのCOPY)
本命のパターンを検証します。
S3を東京リージョン以外に作成し、先程と同じファイルをアップロードしておきます。
今回はバージニア北部(us-east-1)に作成しました。
aws s3 ls --recursive s3://copy-test-us-east-1 2021-01-12 11:20:03 26 copy/sample.csv 2021-01-12 11:20:15 2196 copy/sample.parquet
先ほどと同じようにpsqlで接続し、COPY文を実行します。
csv:
testdb=# COPY public.copy_test FROM 's3://copy-test-us-east-1/copy/sample.csv' IAM_ROLE 'arn:aws:iam::1234567890:role/moriwaki-redshift-test-role' CSV IGNOREHEADER 1 REGION 'us-east-1'; INFO: Load into table 'copy_test' completed, 5 record(s) loaded successfully. COPY
csvはうまくいきました。
parquet:
testdb=# COPY public.copy_test FROM 's3://copy-test-us-east-1/copy/sample.parquet' IAM_ROLE 'arn:aws:iam::1234567890:role/moriwaki-redshift-test-role' PARQUET REGION 'us-east-1'; ERROR: REGION argument is not supported for PARQUET based COPY
エラーになりました。そもそも、「REGION」オプションを指定することすらできませんでした。。
ちなみに、REGIONオプションを指定しないと以下のようなエラーになります。
testdb=# COPY public.copy_test FROM 's3://copy-test-us-east-1/copy/sample.parquet' IAM_ROLE 'arn:aws:iam::1234567890:role/moriwaki-redshift-test-role' PARQUET; ERROR: S3ServiceException:The S3 bucket addressed by the query is in a different region from this cluster.,Status 301,Error PermanentRedirect,Rid BSCRBV5KEK4V2JAG,ExtRid vCvFPh u4iQ8vHuKAJK3/Bt9TY/lJXGFaBfLa9wcJ9jq/YQWrtkSshesk6N6tzU6J+44k+qbyNd8=,CanRetry 1 DETAIL: ----------------------------------------------- error: S3ServiceException:The S3 bucket addressed by the query is in a different region from this cluster.,Status 301,Error PermanentRedirect,Rid BSCRBV5KEK4V2JAG,ExtRid vCvF Phu4iQ8vHuKAJK3/Bt9TY/lJXGFaBfLa9wcJ9jq/YQWrtkSshesk6N6tzU6J+44k+qbyNd8=,CanRetry 1 code: 8001 context: Listing bucket=copy-test-us-east-1 prefix=copy/sample.parquet query: 2639508 location: scan_range_manager.cpp:672 process: padbmaster [pid=3210] -----------------------------------------------
Parquetファイルがクロスリージョンに対応していないことは、以下のドキュメントに記載があります。
https://docs.aws.amazon.com/ja_jp/redshift/latest/dg/copy-usage_notes-copy-from-columnar.html
Amazon S3 バケットは Amazon Redshift クラスターと同じ AWS リージョンにある必要があります。
Parquetだけでなく、ORC形式もダメみたいです。
csvはOKなのに、カラムナフォーマットがダメなのは不思議ですね。
まとめ
Parquet, ORC形式のデータはクロスリージョンに対応していないことがわかりました。
上記のファイルをRedshiftに取り込みたい場合は、S3バケット、Redshiftのリージョンは必ず同一にしましょう。