[新機能] Amazon Redshift データレイクのデータ更新がシンプルになるUNLOADコマンドのCLEANPATH指定がサポートされました

2021.04.14

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

データアナリティクス事業本部コンサルティングチームの石川です。本日は、新たに追加になったUNLOADコマンドのCLEANPATH指定をご紹介します。S3パスにアンロードする前に、既存のファイルを削除する指定で、データレイクのデータ更新がシンプルになります。早速試してみます。

CLEANPATH指定とは

UNLOADコマンドのCLEANPATH指定は、S3パスにアンロードする前に、既存のファイルを削除します。

例えば、

UNLOAD ('SELECT * FROM tickit.date')
TO 's3://cm-bucket/datalake/tickit/sales/'
IAM_ROLE 'arn:aws:iam::123456789123:role/cm-redshift-fullaccess-role'
CLEANPATH
FORMAT AS PARQUET;

と実行すると、s3://cm-bucket/datalake/tickit/sales/の下のファイルが全て削除された後、このUNLOADコマンドで生成されたファイルがs3://cm-bucket/datalake/tickit/sales/の下に生成されます。

でもここまでは、従来のALLOWOVERWRITE指定と変わりありません。

更にパーティション出力するPARTITION BY指定とともにCLEANPATH指定を使用すると、指定したパーティションフォルダーからのみ既存のオブジェクトが削除され、このUNLOAD操作によって生成された新しいオブジェクトが代わりに保存されます。

UNLOAD ('SELECT * FROM tickit.date WHERE year = 2008 and MONTH = \'JAN\' AND DAY = 2')
TO 's3://cm-bucket/datalake/tickit/sales/'
IAM_ROLE 'arn:aws:iam::123456789123:role/cm-redshift-fullaccess-role'
PARTITION BY (year, month, day)
CLEANPATH
FORMAT AS PARQUET;

CLEANPATH指定の長所

従来、Redshiftで作成されたデータマートをUNLOADコマンドを用いてデータレイクエクスポートする(S3に出力する)ユースケースでは、テーブルデータ全体を毎回S3出力する必要がありました。Redshift Spectrumのベストプラクティスは、大きなファクトテーブルをデータレイクに置きます。この大きなファクトテーブルを毎回S3出力する必要するのは現実的ではありません。そのため、差分のみを出力したり、UPSERTで更新されたデータのみを置き換えたい場合は、UNLOADコマンドのS3出力パスを変更して対処する必要がありました。

今回のPARTITION BY指定とともにCLEANPATH指定を使用すると、更新したいSELECTクエリのWHERE句(述語)を変更するだけで差分更新が容易になります。

例えば、

UNLOAD ('SELECT * FROM tickit.date WHERE year = 2008 and MONTH = \'JAN\' AND DAY = 2')...

のように一日分(WHERE year = 2008 and MONTH = \'JAN\' AND DAY = 2)であれば、従来の方法でもあまり変わらないかもしれませんが、以下のように年(WHERE year = 2008)といった期間で、パーティションの全てのデータを置き換えたい場合は圧倒的に便利です。

UNLOAD ('SELECT * FROM tickit.date WHERE year = 2008')...

CLEANPATH指定してデータを更新してみる

テーブルデータ全体をパーティション出力

最初にテーブルデータ全体をパーティション出力します。

cmdb=# UNLOAD ('SELECT * FROM tickit.date')
TO 's3://cm-bucket/datalake/tickit/sales/'
IAM_ROLE 'arn:aws:iam::123456789123:role/cm-redshift-fullaccess-role'
PARTITION BY (year, month, day)
CLEANPATH
FORMAT AS PARQUET;
INFO:  UNLOAD completed, 365 record(s) unloaded successfully.
UNLOAD

S3に以下のようなデータが生成されます。

% aws s3 ls s3://cm-bucket/datalake/tickit/ --recursive
2021-04-14 21:14:35       1036 datalake/tickit/sales/year=2008/month=APR/day=14/0000_part_00.parquet
2021-04-14 21:14:35        997 datalake/tickit/sales/year=2008/month=APR/day=14/0001_part_00.parquet
2021-04-14 21:14:35       1036 datalake/tickit/sales/year=2008/month=APR/day=15/0000_part_00.parquet
2021-04-14 21:14:35       1048 datalake/tickit/sales/year=2008/month=APR/day=15/0001_part_00.parquet
2021-04-14 21:14:36       1019 datalake/tickit/sales/year=2008/month=APR/day=16/0000_part_00.parquet
2021-04-14 21:14:36       1064 datalake/tickit/sales/year=2008/month=APR/day=16/0001_part_00.parquet
2021-04-14 21:14:36       1089 datalake/tickit/sales/year=2008/month=APR/day=17/0001_part_00.parquet
2021-04-14 21:14:36       1036 datalake/tickit/sales/year=2008/month=APR/day=18/0000_part_00.parquet
2021-04-14 21:14:36       1019 datalake/tickit/sales/year=2008/month=APR/day=18/0001_part_00.parquet
2021-04-14 21:14:36        997 datalake/tickit/sales/year=2008/month=AUG/day=31/0000_part_00.parquet
2021-04-14 21:14:36       1019 datalake/tickit/sales/year=2008/month=AUG/day=32/0000_part_00.parquet
:
:
2021-04-14 21:14:52       1036 datalake/tickit/sales/year=2008/month=SEP/day=40/0000_part_00.parquet
2021-04-14 21:14:52        997 datalake/tickit/sales/year=2008/month=SEP/day=40/0001_part_00.parquet

2008年4月のデータのみパーティション出力

Redshift上の2008年4月のデータのみが更新されたと仮定して、この期間のデータをパーティション出力します。

cmdb=# UNLOAD ('SELECT * FROM tickit.date  WHERE year = 2008 and MONTH = \'APR\'')
TO 's3://cm-bucket/datalake/tickit/sales/'
IAM_ROLE 'arn:aws:iam::123456789123:role/cm-redshift-fullaccess-role'
PARTITION BY (year, month, day)
CLEANPATH
FORMAT AS PARQUET;
INFO:  UNLOAD completed, 30 record(s) unloaded successfully.
UNLOAD

2008年4月のデータ(month=APR)のみが更新されたことがタイムスタンプの変化から確認できました。

% aws s3 ls s3://cm-bucket/datalake/tickit/ --recursive
2021-04-14 21:19:01       1036 datalake/tickit/sales/year=2008/month=APR/day=14/0000_part_00.parquet
2021-04-14 21:19:01        997 datalake/tickit/sales/year=2008/month=APR/day=14/0001_part_00.parquet
2021-04-14 21:19:01       1036 datalake/tickit/sales/year=2008/month=APR/day=15/0000_part_00.parquet
2021-04-14 21:19:01       1048 datalake/tickit/sales/year=2008/month=APR/day=15/0001_part_00.parquet
2021-04-14 21:19:01       1019 datalake/tickit/sales/year=2008/month=APR/day=16/0000_part_00.parquet
2021-04-14 21:19:01       1064 datalake/tickit/sales/year=2008/month=APR/day=16/0001_part_00.parquet
2021-04-14 21:19:02       1089 datalake/tickit/sales/year=2008/month=APR/day=17/0001_part_00.parquet
2021-04-14 21:19:02       1036 datalake/tickit/sales/year=2008/month=APR/day=18/0000_part_00.parquet
2021-04-14 21:19:02       1019 datalake/tickit/sales/year=2008/month=APR/day=18/0001_part_00.parquet
2021-04-14 21:14:36        997 datalake/tickit/sales/year=2008/month=AUG/day=31/0000_part_00.parquet
2021-04-14 21:14:36       1019 datalake/tickit/sales/year=2008/month=AUG/day=32/0000_part_00.parquet
:
:
2021-04-14 21:14:52       1036 datalake/tickit/sales/year=2008/month=SEP/day=40/0000_part_00.parquet
2021-04-14 21:14:52        997 datalake/tickit/sales/year=2008/month=SEP/day=40/0001_part_00.parquet

まとめ

恐らくリリースノートを見ただけではピンとこないかもしれないCLEANPATH指定のサポートですが、Lake Houseアーキテクチャを支える機能として必要なアップデートではないかと感じています。このようなユーザーからのフィードバックを素早く対応するのもRedshiftの強みと言えるでしょう。