データサイエンス

面倒なスキーマ定義を自動で行いRedshiftのテーブルを楽に作成する方法

どうも、アナリティクス&デベロップメント部のTです。

最近数十~100GBほどのcsvデータを分析するという場面に遭遇しました。

通常ならGCPのBigQueryかな、ってとこなのですが、
今回はクライアントさんがAWSしか使用していなかったので、
代わりにRedshiftを使うことにしました。

***

さて、Redshiftに限らず、RDBで新しいテーブルを作成する際は、CREATE TABLEで最初にスキーマカラム名、データ型など)を定義しなくてはいけません。

これ、カラムが少ないデータだったらまだいいのですが、10列、20列、それ以上… とあるデータに対して、
各カラムの名前・型云々を一個一個て入力していくのって、超絶面倒です。

しかも一度テーブルを作成してしまったら、あとから細かい修正を加えるのも手間がかかります。

***

そこで本記事のお話ですが、AWS GlueというサービスをRedshiftと組み合わせて使えば、面倒なスキーマ作成・編集をかなり楽に行うことができます。

ポイントとしては以下の2つです。

  • Glueでcsvファイルをパースすることで、スキーマを自動で定義できる(データカタログの作成)
  • Glueで定義したスキーマをもとにRedshiftから直接csvファイルを読み込むことで、データを確認しつつ並行してスキーマ編集もできる

解説

AWS Glueとは?

AWS GlueはサーバーレスのETLツールで、データ整形・加工といった処理をバッチで行う際に使われます。

今回はそのうち一部、データカタログを作成する部分のみを利用します。

Glueでデータクローラを作成すると、S3などのデータレイク内にあるオブジェクトをパースして、データカタログを作成することができます。

とくに、csvなどの構造化されたデータファイルをターゲットとした場合、カラム名・型などの情報を自動的に推定し、スキーマを定義してくれます。

Glueで作成したデータカタログをRedshfitやAthenaといったDBから読み込むことで、手動でスキーマを定義せずにテーブルを作成することができます。

例えばとあるS3バケットtest_for_blogという名前のディレクトリ下に、以下のようなcsv形式のデータファイルが置いてあるとします。

piyo1, piyo2, piyo3
1, 2, hara
3, 4, hetta
5, 6, meshi

これをGlueからクロールすることで、以下のようなデータカタログが作成されます。

f:id:gri-blog:20191227124648p:plain

データカタログは、DB>テーブルの2階層から成り、今回はDB名glue_dbと設定してあります。

テーブル名はS3の参照ディレクトリ名から自動的にtest_for_blogと設定されました。

読み込んだcsvファイルの内容通りに、テーブルtest_for_blogスキーマが書き込まれていることが分かります。

データカタログ作成方法の詳細を知りたい方は公式ドキュメント等を参照しながら動かしてみてください。

Redshift Spectrumについて

概要・利用開始方法

Redshiftは分散処理のために複数のクラスターから構成されたDBで、通常はクラスター内部にテーブルが保存されています。

一方で、内部テーブルを使わずに、S3に保存されているデータファイルを直接参照することもできます(Redshift Spectrum)。

この方法を使うと、csv等のデータをあたかもRDBテーブルであるかのように参照・操作することができます。

これを行うには、Glueで作成したデータカタログを外部スキーマとして読み込むだけです。

以下のようなクエリをRedshfitのエディタから実行します。

CREATE EXTERNAL SCHEMA glue_schema
FROM DATA CATALOG
DATABASE 'glue_db' --データカタログのDB名
IAM_ROLE 'xxxxxxxxxxxxxxxxxxxxx' --RedshiftからGlueにアクセスするためのIAMロールのARN
CREATE EXTERNAL DATABASE IF NOT EXISTS;

IAMロールARNについては、あらかじめRedshiftクラスターにAmazonS3ReadOnlyAccessAWSGlueConsoleFullAccessを付与しておき*1、そのロールのARMをIAMコンソールからコピーして貼り付けてください。

これにより、先ほど作成したカタログ内のDB glue_dbを、glue_schemaという名前でRedshiftに取り込むことができます。

Redshiftのクエリエディタからスキーマ一覧を見るとglue_schemaが追加されており、その下にあるtest_for_blogというテーブルから先ほどのcsvファイルの中身を参照することができます。

f:id:gri-blog:20200107095201p:plain

データ参照方法は、通常のテーブルとまったく同じです。

SELECT * FROM glue_schema.test_for_blog
LIMIT 10;

特徴・利用ケース

Redshift Spectrumの特徴は、スキーマとデータが別々に定義・保存されていることです。
これにより、スキーマの編集を楽に行うことができます。

内部にテーブルを持つ場合、スキーマを編集するにはデータごと書き換えなくてはいけません。

一方でRedshift Spectrumの場合、Glueからデータカタログの編集を行うだけで、スキーマの変更が即座に反映されます。
この時、S3に保存されたcsv等のデータファイルは一切いじる必要がありません。
そのため、データを確認しつつ随時カラム名や型の修正を行うことも楽にできます。

一方でRedshift Spectrumのデメリットとしては、内部テーブルと比べてレスポンスが遅い場合があること、Viewの作成ができない、といったことが挙げられます。
レスポンスについては、特にキャッシュが有効な場合は内部テーブルの方が速いようです。*2

よく参照するデータの場合、一通り確認・スキーマの編集が終わった段階でRedshiftの内部テーブルとして取り込んでしまうことをお勧めします。

やり方は簡単。以下のようなクエリを発行するだけです。

CREATE TABLE test_for_blog AS
SELECT * FROM glue_schema.test_for_blog

まとめ

AWS Glueを使えば、面倒なスキーマ定義も楽に行えます。
csvファイルだけでなく、tsvやzipであっても同様に行えます。
データカタログ作成時に圧縮形式や区切り文字、改行文字等も識別してくれるからです。

皆さんもぜひ、活用してみてください。

参考

*1:RedshiftクラスターにIAMロールを付与するには、コンソールのクラスター一覧から「IAM ロールの管理」を選択し、設定してください。また、クラスター作成時にも入力欄があります。

*2:本稿で用いたサンプルデータでselectを試したところ、Redshift Spectrumで1.7秒、Redshift内部テーブルで0.5秒でした。