冥冥乃志

ソフトウェア開発会社でチームマネージャをしているエンジニアの雑記。アウトプットは少なめです。

follow us in feedly

AWS Glueのお試し:ドキュメントのざっと読みとクローラを使ってみる

先日、このようなブログが発信されました。

aws.amazon.com

この辺りのデータ環境周りを作るためのサービスは、どんな状況であっても覚えておいて損はないですし、好きなレイヤーでもあるのでちょっと触ってみました。なお、公開されているのはまだ北米リージョンのみです。

ドキュメント読みながら、使いながらメモ書きしてたらある程度のボリュームになったので、一旦区切って出します。

参考リソース

なんにせよ公式リソースが一番ですので、迷ったらここに当たってみましょう。

docs.aws.amazon.com

サンプルや各種ライブラリのリポジトリもすでに作られています。今はまだ少ないですが、これから充実して行くことを期待しています。

github.com

github.com

AWS Glue is 何

AWS上のフルマネージドなETLです。ETLはextract, transform, and loadの略で、ちょっとした規模の企業だと必ずあるデータ連携基盤みたいなものを構築するためのソリューションです。自前で構築しているところもあるでしょうが、ソリューションを使っているところもあります。ちなみに私が仕事で使ったことがあるのは、DataStageとHULFTですね。Embulkあたりも同じ目的で使うことができると思います。Glue(糊、接着剤)とはよく言ったもの。

AWS Glueは雑な理解ですが、様々なシステム、サブシステムが構築されているAWS上(JDBCはおそらくその限りではないはず)のデータリソースの

を取りまとめて、データのやり取りをするジョブにおいて

  • 変換ルール
  • トリガー

を定め、データ連携基盤を作るためのソリューション。

ドキュメントのざっと読みまとめ

先にドキュメントをざっと読んで、コンポーネントやモデルを理解しましょう。大まかに以下のコンポーネントの役割を覚えればいいのではないかと思います。なお、現段階でのジョブやトリガーについては使った上での理解ではないことをご承知おきください。

  • AWS Glue Data Catalog
    • Database
      • Table
      • Connection
    • Crawler
      • Classifier(Custom)
    • Job
      • Trigger

AWS Glue Data Catalog

一つのAWSアカウントに一つ対応するメタデータリポジトリで、全てのテーブル定義、ジョブ定義、クローラ定義を含みます。

Database

スキーマ情報の格納単位と理解すればいいでしょう。ほぼタグとしての扱いなので、現実のデータベースの境界線に必ずしも一致する必要はありません。その配下にデータベースに紐づいたテーブルやコネクションがぶら下がります。

Table,Connection

Tableは各種データソースのスキーマ情報です。データソースに対応しているのはS3かJDBCコネクションのいずれか。DynamoDBはそのままでは対応していないようですが、まあこれはデータ同士をマッピングして連携をするためのものなので、スキーマレスはあまりお呼びじゃないですよ、という感じですね。

ConnectionはJDBC接続の接続情報。スキーマ情報のクローリングやジョブの実行に使います。

Crawler,Classifier

Crawlerはデータストア(S3,JDBC)を指定して定期的にスキーマ情報を取得しに行くための仕掛けです。ETLはすでに作ってある各種サービスや社内システムを繋いで行くものなので、こういうの地味に便利。クローリングスケジュールも設定できて、スキーマ変更もある程度自動で追随できます。スケジュール実行とオンデマンド実行を選べます。

Classifierはデータソースのファイルやバイナリ形式などに応じたスキーマ情報定義のための分類子です。AWS Glueに用意されているものはBuilt-in Classifierと呼ばれ、これらはデータストア読み込み時に自動で確認されます。

docs.aws.amazon.com

上記のBuilt-inではないカスタムなClassifierを作ることもでき、それらはクローラに実行を指定することができます。

Job,Trigger

Jobはデータ変換処理を記載したものです。裏でApache Sparkが動いているらしく、PySpark形式に変換するため、スクリプトPythonで書きます。データ連携でよく利用する基本的な変換ロジック自体はTransformと呼ばれるAPIが提供されていて、自前でゴリゴリ書くというよりはAPIの組み合わせでなんとかすることを最初に考えた方が良さそうです。作成したJobをダイアグラムとしても確認できるようです。ダイアグラムベースに開発できるわけではないようなので、開発の補助的な役割と実行時の状態可視化に使うためのものではないかと思います。

Triggerは実行タイミングの制御です。AWS Glueで対応しているのはcron形式のスケジューラ、他のジョブの完了検知、オンデマンド実行です。AWSの他のサービスの実行状態なんかをトリガーにする場合は、おそらく対応するイベントで発火するLambdaファンクションを書いて、その中からオンデマンド実行という流れがいいのではないかと思います。

お試しの準備

ETLはそのソリューションの特性上、インターネットにオープンにして使うものではありませんのでVPCの利用が前提になります。ドキュメントにも一通りこの辺りは整備されていますので、参照して環境を作っていきましょう。

docs.aws.amazon.com

なお、S3 to S3のようにサービス上のやりとりになる場合はなくても動くようです。JDBCでアクセスするリソースの場合も同様にVPCの設定が必要です。

クローラを作ってみる

いつまでもドキュメント読むのも疲れるので、少し触って理解しましょう。クローラを作ってS3に放り込んでいるファイルからスキーマ情報を抜き出してみます。S3に放り込んだcsvスキーマ定義とjsonスキーマ定義のためのクローラを作ります。

なお、クローラの作り方そのものは先のブログや公式の方が詳しいので、そちらを説明するよりも、こういう風に使ったらこういう挙動になる、という感じの部分を主に載せておきます。というわけでクローラが対象にするファイルが一つだけのケースについてはドキュメント通りにやれば特に迷うことはないので割愛します。

同一ファイルを年次などの条件でディレクトリ分けしているケースの取り込み

S3データストアを利用する場合、対象として指定されたS3ディレクトリをルートとして、以下の条件が整っていれば、サブディレクトリをパーティションキーとしてスキーマ定義を行います。

  • 同一形式のファイルであること
  • 配下のファイルのカラム構成が同じであること
  • 圧縮の形式が同じであること

例えば、年度のごとのディレクトリを以下のように配置して、バケットをデータストアとして指定した場合のクローリング結果をみてみましょう。

/bucket-name
  /2017
    /csv
      /file.csv
  /2016
    /csv
      /file.csv

クローリングのスキーマの内容は以下のようになります。

f:id:mao_instantlife:20170819092240p:plain

ファイルの項目以外にパーティション用の項目が追加されていますね。まだジョブを触っていないので、具体的にどう使うかはイメージついてないですが、おそらくこれを使ってジョブで読み込むデータをフィルタリングしたり、振り分けたりするのでしょう。

実際のパーティションの状況もみることができます。

f:id:mao_instantlife:20170819092256p:plain

当たり前ですが、この辺、ディレクトリ構成なども含めたデータ設計をやっておかないと実務上で綺麗に仕掛けることは難しいと思います。

複数データストア(ファイル形式が異なる)から読み込んでみる

ドキュメント読んでいて気づいたのですが、意外とクローラのリミットが小さいんですよね(今後大きくなるかどうかは不明)。アカウントごとに10個ですよ。

docs.aws.amazon.com

なので、データストア一つにつき一つのクローラを定義する、といった富豪的な使い方ができません。データのグループごとにまとめて定時実行という戦略を立てる必要があります。この辺のグルーピングの仕方とか境界の引き方というのも割とセンスが出そうですね。

というわけで他のシステムが持っている関連する別テーブル(ファイル)がjsonで出力されているというシナリオで、先と同じクローラで一緒に処理をするということもできます。以下のようにクローラに対して複数のデータセットは普通に指定することができます。

f:id:mao_instantlife:20170819092355p:plain

jsonファイル指定時の注意

何ですが、実行時に少しハマりました。今回追加したデータは、airport.jsonというGithubに公開されていたjsonファイルを使ってクローラを実行したのですが、結果のClassifier情報が UNKNOWN になってしまいました。スキーマ情報も空。csvの方は今までと同様にスキーマ情報を取得できているので、うまく取得できなかったようです。

というわけで立てた仮説は以下。

  1. クローラごとにClassifierは固定される
  2. jsonファイルがおかしい

1を確認するために、jsonファイルのクローラを単独で作って実行。同じようにUNKNOWNになったので否定されました。ドキュメントを見ても仮説を裏付けるような記載はなかったので、データストアごとにClassifier指定のロジックは働くと見ていいでしょう。

2は、jsonがおかしいというよりもjsonファイルのClassiferが使っているライブラリのjsonパースが仕様に沿っていないというべきでしょう。この可能性に気づいたのはファイルの中身を改めて見た時です。このファイル、トップレベルに配列がきているデータなんですね。で、配列を外してカンマ区切りのオブジェクトの羅列にしてクローリングしてみると以下のように取り込めます。

f:id:mao_instantlife:20170819092335p:plain

これ、会社のプロダクトでも同じような経験があって、おそらくjsonのパースにjacksonを使っているのではないかと思われます。jsonの仕様としてトップレベルに配列を持ってくることは禁じられていないはずなのですが、デフォルトではこれをうまくパースしてくれないからClassifierがUNKNOWNになってしまった、といったところでしょうか。この辺りはjsonでデータ出力するときに考慮しておくべき内容ではないかと思います。

今回のまとめ

クローラのお手軽さがいいですね。RDSはまだ試していませんが(サンプル用にスキーマ作るの面倒臭い、誰かいいサンプル持ってないですか?)、使うハードルが同じくらいであれば非常に楽だと思います。ETLはデータを他のデータにロードするためのものなので、input/outputはある程度形式化でき、ジョブで実際に動くビジネスロジックもある程度形式化してきます。そのため、この辺りのものについては使い勝手以外の面で各ソリューションで差別化しづらいのかな、と。AWS Glueについてはそれよりも、連携基盤を作るために必要なデータを集めてくるところの手軽さに注力している感じがしていいですね。Lambdaと組み合わせると柔軟なジョブ起動もできそうなので、他の機能を試すのが楽しみです。

これから試そうと思っているのは以下です。またメモが溜まってきたらエントリにまとめて放出します。

  • ジョブ、トリガー
  • 開発用エンドポイントの作成 Zeppelinとか使うらしいですが、触ったことがないので全くイメージが湧きませんでした。作り方はドキュメントにあります。 Using Development Endpoints for Developing Scripts - AWS Glue
  • コンソールだけで開発するのしんどいのでGithubに置ける形でプロジェクト構成できないか調べてみる これ、Serverless Frameworkみたいなの作る、とか変な方向に行きそうで藪蛇感満載です。