webエンジニアの風速です。
今回はAmazon Athenaを業務内で使用して日付でパーティションの射影をするのに苦労したので、そちらをまとめられたらと思います。
Amazon Athenaとは
Amazon Athenaは、SQLを使用してS3内のデータを直接分析に利用できたりするクエリサービスです。サーバーレスで、読み込んだ容量に応じて課金されるシステムになっています。データ1TBあたり5.00USDらしい(ap-northeast-1)
S3内のcsvなどのデータを読み込んで実際のrdbのテーブルのように操作可能です。
パーティションとは
パーティションという機能はAthena以外にもrdbの機能にあるもので(調べて初めて知った)、テーブル内のデータを格納する場所を分けられる機能です。
Athenaでは読み込むデータによって課金されるため、デイリーとかで動かす場合はかなり重要で、公式も料金かなり削減できると言ってます。
パーティション射影とは
S3のディレクトリを自動的にパーティション分けしてくれる機能です。テーブル定義のときに設定を書くと、その形式でパーティションを追加してくれます。実際にはテーブルのカラムに追加されるようなイメージ。
テーブル定義
CREATE EXTERNAL TABLE IF NOT EXISTS `test_db`.`test_table` (
`test_column1` string,
`test_column2` string,
`test_column3` string,
)
PARTITIONED BY (
`partition_date` string,
)
ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.OpenCSVSerde'
WITH SERDEPROPERTIES (
'separatorChar' = ',',
'quoteChar' = '\"',
'escapeChar' = '\\'
)
LOCATION 's3://test-stor/'
TBLPROPERTIES (
'projection.enabled'='true',
'projection.partition_date.type'='date',
'projection.partition_date.format'='yyyy/MM/dd/HH',
'projection.partition_date.interval'='1',
'projection.partition_date.interval.unit'='HOURS',
'projection.partition_date.range'='2024/06/18/00/,NOW',
'storage.location.template'='s3://test-stor/${partition_date}/',
'write.compression'='GZIP'
);
今回は非Hive形式で格納されているcsvファイルを解析するテーブルを使用します。
s3上のtest-stor
バケットに以下のようにディレクトリ分けされているのを想定しています。
s3://test-stor/yyyy/MM/dd/HH/test.csv
PARTITIONED BY
句のところにパーティション射影したい名前を定義します。
'projection.enabled'
はパーティション射影をするかの設定です。
projection.partition_date.type
はパーティションする型で今回は日付でパーティションしたいので'date'
としています。ほかにも型はありますが今回は紹介しません。
'projection.partition_date.format'
はパーティションするディレクトリの日付の形式を指定します。
'projection.partition_date.interval'
はパーティションする間隔を設定できます。今回は1としているので、'projection.partition_date.interval.unit'
がHOURSなので1時間ごとにパーティションを作成するという設定になっています。
'projection.partition_date.range'
は'from,to'
のイメージで、to側にNOWとすると、現在の時刻をfromとしてくれます。ただUTCなので取得する際は時差に注意が必要です。
'storage.location.template'
はパーティションしたいディレクトリを指定します。
ディレクトリの直下すべてが対象となるので、パーティションしたディレクトリ以下の構成はいろいろ分けても大丈夫だと思いますが、除外設定等できないと思うので、違ったファイル形式のものを置くのは避けた方が良いと思います。
SELECTの例
以下のようにpartition_dateをWHEREの条件に指定でき、対象のディレクトリにあるファイルを読み込んでくれます。
SELECT
test_column1,
test_column2,
test_column3
FROM
test_table
WHERE
test_table.partition_date = '2024/06/18/01'
まとめ
パーティション射影はかなり楽にパーティションを作成でき、読み込むファイルも節約できるのですが、設定のドキュメントが個人的に分かりにくかったので、今回の記事を作成しました。すこしでも参考になれば幸いです。
参考