Amazon Athena: テーブルデータの洗い替え・追加を試してみる #reinvent

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

新サービス Amazon Athenaは、S3上のCSVファイルにテーブル定義(CREATE EXTERNAL TABLE)を適用するだけで、ファイルに変更を加える必要なく、クエリを実行することができます。他の類似サービスのように、CSVファイルをロードし直したり、変換する必要が無い点が他のサービスと異なります。 今回は、CSVファイルを置き換えることでテーブルデータを洗い替えや、CSVファイルを追加することでテーブルデータが追加できるだろう!という仮説を検証してみたいと思います。

今回はデータの更新パターンとして、以下の2つのパターンを試してみます。

  • テーブルデータの洗い替え(S3ファイルの上書き)
  • テーブルデータの追加(S3ファイルの追加)

データファイルの指定は S3のデータフォルダ

データファイルの指定は CREATE EXTERNAL TABLE の LOCATION パラメータに S3のデータフォルダ※1を指定します。S3のデータファイルではありません。なので、テーブルに入れたいデータは LOCATION パラメータで指定した S3のデータフォルダにデータファイルを保存します。

※1 S3のデータフォルダ
正確にはS3に「フォルダ」なんてものはありませんが、便宜上「フォルダ」と表現します。

テーブルデータの洗い替え

顧客や商品、区分といったマスタテーブルのように比較的サイズが小さいテーブル場合などは、データを全て削除して、全てのデータをロードしなおす、つまりデータの『洗い替え』のパターンが一般的です。Amazon Anthena においてはS3上の『データファイル(複数) ≒ テーブルデータ』となりますので、ファイルの上書きで簡単にデータを洗い替えができるはずです。

テーブルを定義します。

CREATE EXTERNAL TABLE IF NOT EXISTS default.users_replace (
  id int,
  name string,
  created date
)
ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe'
WITH SERDEPROPERTIES (
  'serialization.format' = ',',
  'field.delim' = ','
) LOCATION 's3://cm-datalake/users/replace/';

s3://cm-datalake/users/replace/ の下に 最初は2レコードのみのファイルを用意し、後で4レコードのファイルに上書きします。

1,kamikawa,2016/12/01
2,shimokawa,2016/12/02
    ⬇
1,kamikawa,2016/12/01
2,shimokawa,2016/12/02
3,ukawa,2016/12/03
4,sakawa,2016/12/04

s3://cm-datalake/users/replace/ の下に users.csvというファイル名でコピーします。

最初は2レコードのみですが、

20161206-users_1st

最初は4レコードに更新されることが確認できました。

20161206-users_2nd

今回は1つのファイルで確認しましたが、複数ファイルでも同じ結果が得られることを確認しています。ファイルを1つにするS3の特性を活かしてダーティーリードを防止できるのではないかと考えています。逆に複数ファイルにすると結果整合性なのでタイミングによっては古いファイルと新しいファイルのデータを混在したデータを取得してしまうことが想定されます。

テーブルデータの追加

マスタファイルが複数に分かれていたり、差分データのみを追加したいこともあるでしょう。 Amazon Anthena においてはS3上の『データファイル(複数) ≒ テーブルデータ』となりますので、ファイルの追加で簡単にデータの追加ができるはずです。

テーブルを定義します。

CREATE EXTERNAL TABLE IF NOT EXISTS default.users_append (
  id int,
  name string,
  created date
)
ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe'
WITH SERDEPROPERTIES (
  'serialization.format' = ',',
  'field.delim' = ','
) LOCATION 's3://cm-datalake/users/append/';

最初は2レコードファイル、更に2レコードのファイルをフォルダに追加します。

1,kamikawa,2016/12/01
2,shimokawa,2016/12/02
    <strong>+</strong>
3,ukawa,2016/12/03
4,sakawa,2016/12/04

s3://cm-datalake/users/replace/ の下に最初に users_01.csv をコピーした後、users_02.csv を追加でコピーします。

最初のファイルの2レコードのみですが、

20161206-users_01

最初のファイルの2レコードに加え、後のファイルの2レコードが追加されていることが確認できました。

20161206-users_01-02

まとめ

LOCATIONプロパティに指定しているS3フォルダのデータを更新・追加するだけで簡単に、テーブルデータを更新することができることが確認できました。比較的小さなデータにおいては有効な方法である考えられます。

一方、日々の売上データやウェブログ等、トランザクションテーブルのように日々蓄積される時系列データの場合などは、日々のデータを追加する『時系列データ』のパターンが一般的です。これらのユースケースではデータが非常に大きく、日々増加しますので今回紹介した「テーブルデータの追加」の方法では、データのスキャンが日々増加することで、処理時間やAWS利用費(Price Per Query:$5 per TB of data scanned.)の観点で運用が破綻してしまうでしょう。この問題を解決するにはテーブルデータの『パーティショニング』をご検討ください。