RedshiftにParquetファイルをCOPYしたい場合、S3バケットのリージョンに注意が必要です

2021.01.12

データ・アナリティクス事業本部の森脇です。

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のリージョンは必ず同一にしましょう。

参照