Amazon Athenaを使ってみました #reinvent

eyecatch_athena

こんにちは、小澤です。
今回はre:Invent 2016で発表されたというAthenaというものを使ってみました。

Athenaとは

S3上にあるデータに対して直接テーブル定義を行って、SQLでデータの取得が行えるもののようです。
RedshiftやEMRのようにコンピューティングのためのインスタンスを生成する必要がないのも特徴です。
また、JDBC経由だけでなく、Web UI上から対話的にSQLを発行できるようになっており非常に手軽に使えるのも魅力的です。

今回はこのWeb UIからSQLを発行してどのような動きをするのか見てみたいと思います。

使ってみる

まずはサンプルで動かしてみる

サービス一覧上では「分析」の項目に存在していました。
現状ではアメリカのバージニアとオレゴンの2つのリージョンにしか対応していないようなので、そのどちらかで選択する必要があります。

services

Getting Startから実際に操作できる画面に飛ぶと左側にテーブル一覧、右上がSQLを記述するフォーム、右下が実行結果を表示する部分になっている画面が表示されます。
サンプルのデータベースとテーブルも用意されているので、まずはそちらに対して簡単なSELECT文を発行してみました。

select

データを用意して読み込む

次に、S3上にデータを用意してそちらを使ってみます。
今回はUCIにあるAdult Data Setというのを使います。怪しげな名前のデータですが、変なデータではありません。

このデータの一部はこのようになっており、32562件あります。

39, State-gov, 77516, Bachelors, 13, Never-married, Adm-clerical, Not-in-family, White, Male, 2174, 0, 40, United-States, <=50K
50, Self-emp-not-inc, 83311, Bachelors, 13, Married-civ-spouse, Exec-managerial, Husband, White, Male, 0, 0, 13, United-States, <=50K
38, Private, 215646, HS-grad, 9, Divorced, Handlers-cleaners, Not-in-family, White, Male, 0, 0, 40, United-States, <=50K
53, Private, 234721, 11th, 7, Married-civ-spouse, Handlers-cleaners, Husband, Black, Male, 0, 0, 40, United-States, <=50K
28, Private, 338409, Bachelors, 13, Married-civ-spouse, Prof-specialty, Wife, Black, Female, 0, 0, 40, Cuba, <=50K

こちらをS3上にアップロードして、テーブルを作成します。
テーブルの作成はCREATE TABLE文を記述するか、UI上で対話的に行うことが可能なようです。まずは対話的に行ってみます。

table1.2

データベースの選択やテーブル名に関する設定を最初に行います。
「Location of Input Data Set」はS3上のパスを指定しますが、こちらはディレクトリ単位での指定となります。 また、パスの最後の「/」は必須なのでご注意ください。

スクリーンショット 2016-12-01 10.58.49

次にファイルの形式を選択します。
今回はデータセットがカンマ区切りになっていたので、CSVを選択しました。
ParquetやORCといったHadoopでよく利用されるカラムナストレージの選択もできます。ファイル自体をあらかじめその形式に変換しておく必要はありますが、こちらを利用することでディスクIOの効率などを向上させることができるでしょう。 スクリーンショット 2016-12-01 10.59.58

次にカラムの設定を行います。 今回はデータセットの説明ページに書いてある内容で設定していきます。 スクリーンショット 2016-12-01 11.00.56

最後にパーティションの設定も行えるようです。
今回は単一ファイルのデータなので、特に指定はしていませんが、実用上は日付などでパーティションをわけるなどといった方式をとることになるかと思います。 スクリーンショット 2016-12-01 11.05.53

テーブルの作成が完了すると、作成するのに使ったCREATE TABLE文が表示されます。

CREATE EXTERNAL TABLE IF NOT EXISTS cm_ozawa_testdb.adult (
  age int,
  workclass string,
  fnlwgt int,
  education string,
  education_num int,
  marital_status string,
  occupation string,
  relationship string,
  race string,
  sex string,
  capital_gain int,
  capital_loss int,
  hours_per_week int,
  native_country string,
  label string
)
ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe'
WITH SERDEPROPERTIES (
  'serialization.format' = ',',
  'field.delim' = ','
) LOCATION 's3://<S3 bucket name>/<table name>/';

こちらを見るとデータの場所やフォーマットの設定はHiveの記法になっており、HiveのSerDeを利用しているように見えます。
パーティションを設定した場合もおそらくHiveと同様な構造になるのではないかと予想されます。

このテーブルに対してSELECT文を発行してみると、age以外の数値カラムに値が入っていないように見えます。

スクリーンショット 2016-12-01 11.12.26

これは元のデータにカンマの後にスペースが含まれていたのが原因のようでした。
解決策はいくつかあると思いますが、今回はCSVでの読み込みの流れを確認したかったので、元のデータを修正することで対応しました。

SELECT文の結果からテーブル作成

さて、こういったことができるとなると次にSELECT文の結果から別なテーブルを作りたくなります。
試しにORC形式への変換を行うCREATE TABLE AS SELECT ... の実行をしてみます。

error

エラーとなりました。 公式のドキュメントによると、

Athena does not support, for example, CREATE TABLE AS SELECT, which creates a table from the result of a SELECT query statement.

となっており、どうやらこの構文に対応していないようです。
ParquetやORCを扱いたいときには先に生成しておく必要がありそうです。

その他の機能

UI上から実行したSQLの保存や履歴の閲覧が可能です。
また、出力結果についてもCSVでダウンロードが可能なようです。

「Catalog Manager」のタブからはデータベースやテーブルのスキーマ情報なども参照可能なため、カラム数が多いなど複雑なテーブルが増えてくるとこちらも役に立つかと思います。

使ってみての感想

大規模なデータを扱うときには、その内容の確認などに非常に苦労させられることが良くあります。
コンピューティングリソースを用意せずにS3に対してこのような操作が行えるのは、そういったことを手軽が行うための仕組みとしては非常に便利なように感じます。
一方、CREATE TABLE AS SELECTのような構文に対応していないことからも伺えるように、Athenaを利用して新たなデータを生成するといった用途は想定されていないようなので、データの確認やJDBCを利用してBIツールなどから利用するような閲覧側の用途が主になるかと思います。

ParquetやORCに対応していることから、EMRを多く使っているといった場合などで有効に活用できるのではないかと思います。

また、今回はデータの規模も小さいため速度などの検証は行いませんでした。 そんなにストレスを感じるほどの遅さはありませんでしたが、データ量に対して処理時間がどのような変化するかは一度確認しておく必要がありそうです。

終わりに

AWSのAthenaを使ってみました。
今回は簡単な利用だけとなりますが、それでもデータを見る際の手軽さという点に魅力を感じました。
今後はRedshiftやEMRと比較しての利用シーンの使い分けなども想定する必要ありそうです。