新機能『Amazon Redshift Spectrum』から Amazon Athena のテーブルを参照する

Amazon Redshift SpectrumはAmazon S3にあるデータに対して、Amazon Redshiftから直接クエリを投げる事が出来る機能です。前回のブログで Amazon Redshift Spectrumは RedshiftからS3のデータ用に外部スキーマと外部テーブルを定義すると Amazon Athena に自動的にデータベースとテーブルが追加されるということが判明しました。そこで、今回は逆に Amazon Redshift Spectrum が既存の Amazon Athena のテーブルを参照できるか試してみました。

RedshiftからS3のデータ用に外部スキーマと外部テーブルを定義してテーブルを参照する手順については以下のブログを参照してください。今回はこのブログの続編となります。

S3データを直接クエリ出来る新機能『Amazon Redshift Spectrum』を実際に試してみました

Spectrumの設定・利用手順

Spectrumの設定は Amazon Athena からデータ定義言語(DDL)コマンドを使用してデータベースとテーブルを定義した後、Amazon Redshift からデータ定義言語(DDL)コマンドを使用してテーブルを定義します。

ステップ1:Amazon Redshift 用の IAM ロールを作成する

バックエンドではAmazon Athenaと連携しているので、Amazon Athenaの外部データカタログとAmazon S3のデータファイルにアクセス持つIAMロールを作成してRedshiftクラスタに付与、もしくは権限を追加する必要があります。Amazon Redshiftでロールを使用する方法の詳細については、「IAMロールを使用したCOPYおよびUNLOAD操作の承認」を参照してください。

ここでは mySpectrumRole というロール名に、AmazonS3ReadOnlyAccess と AmazonAthenaFullAccessの2つのマネージドポリシーを付与しています。

20170420-Step1

ステップ2:IAM ロールをクラスタに関連付ける

Amazon Redshiftが外部データカタログとAmazon S3にアクセスすることを許可するIAMロールを作成したら、そのロールをAmazon Redshiftクラスタに関連付けます。ステップ1で作成した IAMロールの ロール ARN は外部テーブルを定義する際に利用します。

20170420-Step2

AWS Management Consoleにサインインし、Amazon Redshiftコンソール を開き、ステップ1で作成したmySpectrumRole を選択します。

20170420-Step2-attachedrole

ステップ3:Amazon Athena に データベースとテーブルを作成

Redshift から照会する Amazon Athena のデータベースとテーブルを作成します。

データベースの作成

データベースが存在しない場合はデータベースを作成します。

CREATE DATABASE IF NOT EXISTS spectrumdb;

テーブルの作成

後で以前のブログで作成した sales テーブルと比較できるように同じテーブル定義の sales_athena を作成します。

CREATE EXTERNAL TABLE IF NOT EXISTS spectrumdb.sales_athena (
salesid int,
listid int,
sellerid int,
buyerid int,
eventid int,
dateid smallint,
qtysold smallint,
pricepaid decimal(8,2),
commission decimal(8,2),
saletime timestamp
)
ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe'
WITH SERDEPROPERTIES (
 'serialization.format' = '\t',
 'field.delim' = '\t'
) LOCATION 's3://awssampledb/tickit/spectrum/sales/'
TBLPROPERTIES ('has_encrypted_data'='false');

20170424-spectrum-with-athena-table

ステップ4:Amazon Redshift に 外部スキーマの作成

外部スキーマは外部データカタログ内のデータベースを参照し、Amazon Athena が Amazon Redshift の代わりにAmazon S3にアクセスを認可するための IAMロールのARN を提供します。Amazon Redshift から Amazon Athena の Hiveメタストアを使用して、データベースを作成します。この例では、外部スキーマを作成するときにAmazon Redshiftでデータベースを作成します。

外部スキーマの作成

外部スキーマを作成するには、CREATE EXTERNAL SCHEMAコマンドを実行します。次のコマンドのIAMロールARNを、手順1で作成したロールARNに置き換えてから、SQLクライアントでコマンドを実行します。

cmdb=# create external schema spectrum
cmdb-# from data catalog
cmdb-# database 'spectrumdb'
cmdb-# iam_role 'arn:aws:iam::123456789012:role/mySpectrumRole';
CREATE SCHEMA

外部テーブルの作成は?

外部テーブルはすでに作成済みの Amazon Athena のテーブルを参照できるため、作成する必要はありません。
外部スキーマ名の一覧を取得できます。
cmdb=# select * FROM pg_external_schema pe join pg_namespace pn ON pe.esoid = pn.oid;
 esoid  | eskind |  esdbname  |                                esoptions                                | nspname  | nspowner | nspacl
--------+--------+------------+-------------------------------------------------------------------------+----------+----------+--------
 707623 |      1 | spectrumdb | {"IAM_ROLE":"arn:aws:iam::123456789012:role/mySpectrumRole"} | spectrum |      100 |
(1 row)

ステップ3で作成した sales_athena テーブルのテーブル定義を確認します。

cmdb=# \x
Expanded display is on.
cmdb=# select * from SVV_EXTERNAL_TABLES;
-[ RECORD 1 ]-----+--------------------------------------------------------------------------------------
schemaname | athena_schema
tablename | sales
location | s3://awssampledb/tickit/spectrum/sales
input_format | org.apache.hadoop.mapred.TextInputFormat
output_format | org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat
serialization_lib | org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe
serde_parameters | {"field.delim":"\t","serialization.format":"\t"}
compressed | 0
parameters | {"EXTERNAL":"TRUE","transient_lastDdlTime":"1492843944"}
-[ RECORD 2 ]-----+--------------------------------------------------------------------------------------
schemaname | athena_schema
tablename | sales_athena
location | s3://awssampledb/tickit/spectrum/sales
input_format | org.apache.hadoop.mapred.TextInputFormat
output_format | org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat
serialization_lib | org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe
serde_parameters | {"field.delim":"\t","serialization.format":"\t"}
compressed | 0
parameters | {"EXTERNAL":"TRUE","has_encrypted_data":"false","transient_lastDdlTime":"1492964468"}

ステップ4:Amazon S3でデータを照会する

SPECTRUM.SALESテーブルの行数を取得します。

Timing is on.
cmdb=# select count(*) from spectrum.sales_athena;
 count
--------
 172462
(1 row)

Time: 1211.174 ms

制限事項

執筆時点では、Amazon Redshift Spectrum がサポートしていない SerDeを利用した Amazon Athena のテーブルはエラーとなります。例えば、jsonのSerDe(org.openx.data.jsonserde.JsonSerDe)などを実行すると以下のようなエラーが出力されます。

cmawsteamdb=# select * from athena_default.json_athena;
ERROR: External Catalog Error: Unsupported file format. org.apache.hadoop.mapred.TextInputFormat org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat org.openx.data.jsonserde.JsonSerDe
Time: 326.571 ms

まとめ

想定通り、Amazon Redshift Spectrumは、Amazon Athena のデータベース名に対応する外部スキーマを登録することで、Amazon Athena のテーブルに対してクエリーを実行できることを確認できました。すでに Amazon Redshift と Amazon Athenaをお使いの環境であれば、外部スキーマを定義するだけでこれらのテーブル間の結合や条件フィルタリング、集約が可能になりますのでご活用ください。