カピバラ好きなエンジニアブログ

ITのこととか趣味のカメラのことなどを赴くままに書いていきます。カピバラの可愛さこそ至高。

AppFlowフローで出力したデータをGlue DataBrewで変換する

2021/11に以下のようなアップデートが発表されましたので、ちょっと試してみようと思います。
aws.amazon.com

AppFlow条件確認

AppFlowから出力したデータのすべてがDataBrewで変換できるかと言われるとそうではありません。
ちゃんと条件が決まっています。
docs.aws.amazon.com


主に以下の3つがその条件になります。

  • AppFlowの送信先がS3であること
  • データが集約されていること(Parquet形式では利用不可) ※ただしイベント実行の場合は不要
  • フローが一回以上実行されていること(実行方式は問わない)



あと検証していて気づきましたが、CSVで出力している場合はDataBrew側でデータをスクリーニングするときに圧縮されていないためエラーが表示されて取り込めません。
そのため実質JSON形式のみがサポートされているようです。

実施内容

データセットの作成

それでは早速作成していきます。
まずはGlue DataBrewのコンソールからデータセットを表示し、新しいデータセットの接続を押下します。
f:id:live-your-life-dd18:20211203104320p:plain


データセット名を入力し、AppFlowを選択すると事前に作成しているフローが表示されるので選択してデータセットを作成を押下します。
f:id:live-your-life-dd18:20211203104428p:plain


無事データセットが作成されます。この時点でAppFlowで出力されたS3上のデータをスキャニングしてデータ型が自動で表示されます。
f:id:live-your-life-dd18:20211203104914p:plain


まだフローを作成していない場合はDataBrewの画面からフローを作成を押下すると、送信元のサービスを選択できるようになっており、押下するとAppFlowのコンソールに自動遷移します。
また、先ほどの条件にフローが1回以上実行されていることというのもありましたが、DataBrewのコンソールからフローを実行することもできるようになっています。
f:id:live-your-life-dd18:20211203104617p:plain

プロジェクト作成

データセットが作成できたので、プロジェクトを作成していきます。
f:id:live-your-life-dd18:20211203105020p:plain


プロジェクト名は適当につけます。レシピは新しく作成します。
f:id:live-your-life-dd18:20211203105106p:plain


データセットはマイデータセットを選択すると先ほど作成したAppFlowのデータセットが表示されますので、それを選択します。
アクセス許可は事前に作成しておいたGlue DataBrew用のIAMロールを指定して、プロジェクトを作成します。
f:id:live-your-life-dd18:20211203105149p:plain


プロジェクトを作成するとAWS側でコンピューティングノードが準備されてS3上のファイルのサンプリングが行われます。この設定には数分がかかります。
f:id:live-your-life-dd18:20211203105349p:plain


設定が完了するとこんな感じでサンプリングしたデータがコンソール上に表示されます。
右側のレシピを構築するから変換処理を作成していきます。
f:id:live-your-life-dd18:20211203105454p:plain

レシピ作成

コンソール右側のステップを追加を押下するとどのような変換処理を行うのか選択できます。
f:id:live-your-life-dd18:20211203105604p:plain


AccountNumberカラムがnullのデータをフィルターで除外してみます。
f:id:live-your-life-dd18:20211203110003p:plain


CustomerPriority_cカラムがHighのデータ以外を除外します。
f:id:live-your-life-dd18:20211203110136p:plain


レシピを発行からレシピを作成します。
f:id:live-your-life-dd18:20211203110258p:plain
f:id:live-your-life-dd18:20211203110321p:plain


問題なく作成されました。
f:id:live-your-life-dd18:20211203110356p:plain

ジョブ作成・実行

ジョブを作成を押下します。
f:id:live-your-life-dd18:20211203110434p:plain


名前は適当につけます。
f:id:live-your-life-dd18:20211203110741p:plain


最初にジョブのインプットを設定します。
今回はレシピの実行なので、レシピジョブを作成を選択します。
これまでの手順で作成したデータセットとレシピを指定します。
f:id:live-your-life-dd18:20211203110802p:plain


次にジョブのアウトプットを設定します。
今回はParquet形式、snappy圧縮、暗号化有りで設定します。
f:id:live-your-life-dd18:20211203110954p:plain


ちなみに出力する際に新規のフォルダを作成するのか、ファイル自体を洗い替えするのかを指定できます。
また特定のカラムをパーティション化することもできるので、yearカラムを作って作成しておけばS3上にyear=YYYYのパーティションフォルダが作成されて、自動的にその配下にファイルが格納されます。
f:id:live-your-life-dd18:20211203111114p:plain


後はオプション設定でジョブ実行時のノード数やスケジュール、アクセス許可するIAMロールを設定してジョブを実行します。
ノード数はデフォルトで5になっているので、コストを気にされる方は減らしたほうが無難だと思います。
f:id:live-your-life-dd18:20211203111353p:plain


無事成功したようです。
f:id:live-your-life-dd18:20211203111642p:plain

出力ファイル確認

出力先のS3を見るとファイルが出力されていました。
f:id:live-your-life-dd18:20211203111737p:plain


どうやら出力先は、指定したS3バケット/ジョブ名にランダム文字列を追加したもの/パーティションフォルダ、となるようです。
ファイル名も、ジョブ名にランダム文字列を追加した名前になってました。
このあたりは明示的に特定の名前にするのは難しそうです。


S3 Selectでもファイルの中身が確認できました。
f:id:live-your-life-dd18:20211203112051p:plain

ジョブ実行(2回目)・出力確認

試しにインプットを変更せずに再度実行した場合、同じデータが再度取得されるのか増分のみなのか確認してみます。


で、実行した結果が以下です。見やすさのためにパーティションを少し変えてますが、ファイル自体は作成されているので、どうやらGlue Jobであったようなブックマーク機能はなさそうです。
f:id:live-your-life-dd18:20211203112733p:plain
f:id:live-your-life-dd18:20211203112756p:plain


またバケット直下の出力先も新しくジョブ実行ごとにフォルダが作成されて、その配下に出力されるようですので、これはちょっと使いづらそうです。
f:id:live-your-life-dd18:20211203112908p:plain

ジョブ実行(3回目)・出力確認

ジョブの出力設定でフォルダを作成しないに設定して実行してみます。
f:id:live-your-life-dd18:20211203113151p:plain


想定通りバケット直下にパーティションフォルダが作成されて、その配下にファイルが出力されました。
f:id:live-your-life-dd18:20211203113610p:plain


1つ想定外だったのが直前に出力したジョブ名のフォルダが削除されていたことです。
出力形式を変更すると指定したS3パス配下が洗い替えられてしまうので、変更する際は注意が必要そうです。


ジョブを作成するときはAppFlowで連携するDB・テーブル名を元にdatabase=XXXX/table=YYYY等の名前で出力先を手動で作成しておいて、その配下にジョブから出力するようにした方が管理はしやすいかもしれません。

ジョブ実行(4回目)・出力確認

今度はAppFlow側でフローを再実行して新たにS3にファイルを出力して、DataBrewのジョブを実行してみます。以下がAppFlowから出力したファイルです。
f:id:live-your-life-dd18:20211203114525p:plain


ジョブを実行して出力された結果が以下になります。
てっきり処理対処が増えてサイズがファイル数が倍になっているかと思ったのですがそうではなさそうです。
S3 Selectでファイルの中身を見ても特に重複データは含まれていないので、その辺りは何かしたらの判定をしているのかもしれません。
f:id:live-your-life-dd18:20211203114936p:plain

感想及び所感

色々と試した結果思うのは、実装自体は簡単にできるようになってますが、S3の構成や増分取得か全件取得なのか、変換対象と出力方法がどうなっているのかをちゃんと設計しないと想定外のデータ変換がされてしまった、コストが発生した、といった問題が発生しそうです。

もし使う機会があればその辺りは特に注意したいと思います。