Amazon Athena を使ってみよう

AWSを利用したデータ分析の話です。

蓄積されたログをはじめとする各種のデータを傾向分析や障害調査などでちょっと集計するようなことはよくあると思います。”ファイルを集めてきて必要な情報を切り取って平均値を求める” だけなのですが、数万のファイルを集めてその後Grepする?(マジで…)となる状況を幾度となく見てきました。

でも、最近ではAmazon S3にファイルをおいてあれば、Amazon Athenaで簡単に集計できるようです。


Amazon Athenaとは…

詳しくはAmazon Athenaのページをしらべてみることがオススメです。日々、進化が速いです。
自分は、Athena = SQLとPresto(likeな)関数が使えるHadoop的なSaasと認識しています。


Athenaの概念階層

データを取り扱う上で、Athenaには4つの概念的な階層があります。
いわゆるRDBを思い浮かべるとわかりやすいかと思います。

Layer名前概要制約
1Catalog論理的なデータベースサーバーAWS Account&Regionに対して1つ
2Database複数のテーブル群をまとめるCatalogに対して最大100
3Tableスキーマ定義してデータを格納するDatabaseに対して最大100
4PartitionTableに対して設定するデータパステーブルあたり20K

Athenaにで利用するリソース

AthenaとS3がメインのリソースになります。
なお、S3は

  • 検索対象(例えばログファイル)が配置されているBucket
  • 検索結果を配置するBucket

の2種類があります。

そのほかに2017/8のアップデートでGlueとのインテグレーションもできるようになったようですが、ここでは割愛します。(将来的に調査しようと思います。)

検索を行う前の具体的な作業は、下記のようになります。

  1. 検索対象データをS3に配置する
  2. Athenaの利用リージョンを決定( =Catalogの決定)
  3. Databaseを作成(=Create Database)
  4. Tableを作成 (=Create Table)
    (Amazon S3上の保存されたデータファイルの「パス」と「データスキーマ」を指定)
  5. Partitionを設定(必要があれば)
  6. 検索開始!


検索対象Bucket

検索対象のBucketは、Atnenaの利用リージョンによらず指定が可能です。(Cross Region利用が可能)
ただし、Athenaを実行するユーザーは、検索対象Bucketに対して下記のActionが許可されている必要があります。

  • GetBucketLocation
  • GetObject
  • ListBucket
  • ListBucketMultipartUploads
  • ListMultipartUploadParts
  • AbortMultipartUpload
  • PutObject

(クロスアカウントでの利用時には、Bucket側のアクセスPolicyの設定も必要となります)

検索結果Bucket

Defaultでは、 s3://aws-athena-query-results-[aws.account.id]-[aws.region]/ のディレクトリに出力されます。
マネジメントコンソール上では、右上の[Setting]の箇所で変更することが可能です。
(ちなみに検索結果Bucketは、利用するAthenaと 同一のAWSリージョン とする必要があります。)


Athenaのテーブルを作成

Athenaのベストプラクティスとして、Apache Hive方式のデータパーティションの形式にS3にファイルを格納しておくというパターンがあります。今回はこの形式でログファイルを配置しました。ここでは、Amazon Athenaの提供サンプルを例として利用します。
テーブルのRootディレクトリの中に

  • year=2015
  • month=01
  • day=01

とkey=valueの形式でパーティション用のサブディレクトリを作成して、その中にファイルが配置されています。

S3上のKey構造

$ aws s3 ls s3://athena-examples-[aws.region]/elb/orc/year=2015/month=01/
                           PRE day=01/
                           PRE day=02/
                           PRE day=03/
                           PRE day=04/
                           PRE day=05/
                           PRE day=06/
                           PRE day=07/

配置するログファイル

$ aws s3 ls s3://athena-examples-[aws.region]/elb/orc/year=2015/month=01/day=01/
2017-02-16 00:26:24    6806990 part-r-00151-45043f09-35a3-4db2-bfdd-fe182520ee6a.zlib.orc

あとはAthenaでテーブルを作成します。事前にDatabaseが存在しない場合にはDatabaseも作成しましょう。パーティションのキーを作成した以外は、ほぼAthenaのBluePrintのままです。

AthenaCreateTableQuery

CREATE EXTERNAL TABLE IF NOT EXISTS elb_logs_orc (
  request_timestamp string,
  elb_name string,
  request_ip string,
  request_port int,
  backend_ip string,
  backend_port int,
  request_processing_time double,
  backend_processing_time double,
  client_response_time double,
  elb_response_code string,
  backend_response_code string,
  received_bytes bigint,
  sent_bytes bigint,
  request_verb string,
  url string,
  protocol string,
  user_agent string,
  ssl_cipher string,
  ssl_protocol string )
PARTITIONED BY(
  year int,
  month int,
  day int
)
STORED AS ORC
LOCATION 's3://athena-examples-[aws.region]/elb/orc/'
tblproperties ("orc.compress"="ZLIB")

Athenaのテーブルにパーティションを作成

key=valueの形式でディレクトリが存在していて、テーブル作成時にパーティションのキー指定されていれば、パーティションの作成は非常に簡単です。(この部分が実際の運用では、かなりキモになる部分では無いかと思います。)
Athenaにて下記クエリーを実行すると、新しいS3のディレクトリがあるかを確認して新しいディレクトリが作成されている場合はAthenaのテーブルのパーティションとして追加します。

AthenaRepairTableQuery

MSCK REPAIR TABLE elb_logs_orc

Athenaに検索クエリーを実行

ここまでおわれば、やっとSQLが実行できるようになります。Enjoy Your Athena Life !!!

SELECT * FROM elb_logs_orc

参照

Amazon Athena