やりたいこと
- yyyymmごとに溜まっていくデータを対象とし
- Athenaで扱うためのParquetデータを作成したい(AthenaのCTAS以外で)
- とあるカラムのデータから分散させた partition_number でパーティションを分けたい
- でもyyyymmではパーティション切りたくない
- RedshiftのUNLOADの機能「PARTITION BY」を利用したい
やってみた
まずは1か月分のyyyymmで試します。
unload
('select column1, column2, column3,partition_number from tablename where yyyymm =\'202101\' ')
to 'UNLOAD-TO' CREDENTIALS 'aws_iam_role=MYROLE'
FORMAT AS PARQUET
PARTITION BY (partition_number)
PARALLEL ON allowoverwrite;
PARTITION BYによって自動的に partition_number=xxxxx という形式でUNLOADされてゆきました。
おお素敵!という結果なので、他のyyyymmも続けてやってゆきました。
困った
3か月分くらいが終わったころでしょうか。よしエラーもないなと思いつつ確認をしていると、ファイルのサイズが想定よりかなり少ない状態です。
中身を見てみると、、、最後に実行したyyyymmのデータのみ、しかありません。
ここで気づきました。
そう、yyyymmでパーティションを切っていないので、同じ /partition_number=xxxx/ の下に同じファイル名で次々と上書きされてしまったのです。
通常、UNLOADするときにはUNLOAD先自体にyyyymmをprefix的に入れるなどしてこうしたことを回避します。しかし、PARTITION BY を利用するとそうした指定ができなくなってしまうのです。
また、AthenaのCTASによるParquetおよびPARTITION作成では、prefix的に出力ファイル名に実行時刻みたいなものが自動的に付いたりするので、自動回避できたりもします。
回避方法
以下の方法を採りました
- Athenaで利用はしないがパーティション自体は作成する
unload
('select column1, column2, column3, partition_number ,\'202101\' as yyyymm from tablename ')
to 'UNLOAD-TO' CREDENTIALS 'aws_iam_role=MYROLE'
FORMAT AS PARQUET
PARTITION BY (partition_number,yyyymm)
PARALLEL ON allowoverwrite;
これにより、プレフィックスというか単にパーティションにはなりますが、上書を回避することができました。
無理やりな回避方法にはなりましたが、そもそも処理成功後ファイルのyyyymmが見えることは良いことで
- UNLOADの処理の進捗がわかりやすい
- 処理失敗時の削除などにも便利
というメリットがあります。
感想
書いていて、そもそも「特定のパーティションは切りたいが、yyyymm等のdateパーティションは切りたくない」みたいなケースがレアなのではと思ってきました。