Glue Sparkジョブのスクリプト編集画面のダイアログについて調べてみた

こんにちは。インテグレーション部 の大高です。

Glueと仲良くなるべく色々と触っています。今回はGlue Sparkジョブのスクリプト編集画面のダイアログについて調べてみたいと思います。

Sparkジョブのスクリプト編集画面の場所

まずスクリプト編集画面の場所ですが、GlueのSparkジョブをマネージメントコンソールから選択してから画面下部「スクリプト」タブから「スクリプトの編集」をクリックすることで開くことができます。

ダイアログについて

スクリプト編集画面の左側に表示されているのがジョブの流れを表示したダイアログです。このダイアログはソースコード内のコメントにより自動で生成されます。例として以下のようなコメントとコードがある場合を示します。

## @type: DataSource
## @args: [database = "cm-ootaka-daisuke", table_name = "sample_table", transformation_ctx = "datasource0"]
## @return: datasource0
## @inputs: []
datasource0 = glueContext.create_dynamic_frame.from_catalog(database = "cm-ootaka-daisuke", table_name = "sample_table", transformation_ctx = "datasource0")

## @type: DataSink
## @args: [connection_type = "s3", connection_options = {"path": "s3://foobar/glue/parquet/"}, format = "parquet", transformation_ctx = "datasink1"]
## @return: datasink1
## @inputs: [frame = datasource0]
datasink1 = glueContext.write_dynamic_frame.from_options(frame = datasource0, connection_type = "s3", connection_options = {"path": "s3://foobar/glue/parquet/"}, format = "parquet", transformation_ctx = "datasink1")

この場合「ダイアグラムの生成」ボタンをクリックすると、以下のようにダイアグラムが表示されます。

このようにダイアグラムとして処理の流れが可視化されるのですが、こちらについてもう少し色々試してみたいと思います。

コメントによる自動生成ということは…?

極端な話をすれば、コメントによる自動生成なのでソースコードは不要なはずです。試してみます。

## @type: DataSource
## @args: [database = "cm-ootaka-daisuke", table_name = "sample_table", transformation_ctx = "datasource0"]
## @return: datasource0
## @inputs: []

## @type: DataSink
## @args: [connection_type = "s3", connection_options = {"path": "s3://foobar/glue/parquet/"}, format = "parquet", transformation_ctx = "datasink1"]
## @return: datasink1
## @inputs: [frame = datasource0]

ちゃんと表示されましたね。

DataSourceだけのパターン

DataSourceだけにしてみます。

## @type: DataSource
## @args: [database = "cm-ootaka-daisuke", table_name = "sample_table", transformation_ctx = "datasource0"]
## @return: datasource0
## @inputs: []

何も表示されません。少なくても2つの要素は必要なようです。

DataSourceとApplyMapping(変換処理)

今度はDataSourceとApplyMapping(変換処理)だけにしてみます。

## @type: DataSource
## @args: [database = "cm-ootaka-daisuke", table_name = "sample_table", transformation_ctx = "datasource0"]
## @return: datasource0
## @inputs: []

## @type: ApplyMapping
## @args: [mapping = [("no", "int", "no", "int"), ("title", "string", "title", "string"), ("price", "int", "price", "int")], transformation_ctx = "applymapping1"]
## @return: applymapping1
## @inputs: [frame = datasource0]

こちらも何も表示されません。DataSourceとDataSinkは必要なようですね。

DataSourceとApplyMapping(変換処理)とDataSink

では、DataSourceとDataSinkの間にApplyMapping(変換処理)を挟んだパターンです。

## @type: DataSource
## @args: [database = "cm-ootaka-daisuke", table_name = "sample_table", transformation_ctx = "datasource0"]
## @return: datasource0
## @inputs: []

## @type: ApplyMapping
## @args: [mapping = [("no", "int", "no", "int"), ("title", "string", "title", "string"), ("price", "int", "price", "int")], transformation_ctx = "applymapping1"]
## @return: applymapping1
## @inputs: [frame = datasource0]

## @type: DataSink
## @args: [connection_type = "s3", connection_options = {"path": "s3://foobar/glue/parquet/"}, format = "parquet", transformation_ctx = "datasink2"]
## @return: datasink2
## @inputs: [frame = applymapping1]

よさそうですね。

だんだんパターンが見えてきました。大事なポイントとしては、@inputs@returnの整合性が取れていることと、DataSourceとDataSinkが存在していることのようです。

DataSinkを複数にしてみる

今度はDataSinkを複数にしてみます。

## @type: DataSource
## @args: [database = "cm-ootaka-daisuke", table_name = "sample_table", transformation_ctx = "datasource0"]
## @return: datasource0
## @inputs: []

## @type: DataSink
## @args: [connection_type = "s3", connection_options = {"path": "s3://foobar/glue/parquet/"}, format = "parquet", transformation_ctx = "datasink1"]
## @return: datasink1
## @inputs: [frame = datasource0]

## @type: DataSink
## @args: [connection_type = "s3", connection_options = {"path": "s3://foobar/glue/parquet/"}, format = "parquet", transformation_ctx = "datasink2"]
## @return: datasink2
## @inputs: [frame = datasource0]

## @type: DataSink
## @args: [connection_type = "s3", connection_options = {"path": "s3://foobar/glue/parquet/"}, format = "parquet", transformation_ctx = "datasink3"]
## @return: datasink3
## @inputs: [frame = datasource0]

いい感じですね。

DataSourceを複数にしてみる。

今度はJoinを利用した逆パターンです。

## @type: DataSource
## @args: [database = "cm-ootaka-daisuke", table_name = "sample_table", transformation_ctx = "datasource0"]
## @return: datasource0
## @inputs: []

## @type: DataSource
## @args: [database = "cm-ootaka-daisuke", table_name = "sample_table", transformation_ctx = "datasource1"]
## @return: datasource1
## @inputs: []

## @type: DataSource
## @args: [database = "cm-ootaka-daisuke", table_name = "sample_table", transformation_ctx = "datasource2"]
## @return: datasource2
## @inputs: []

## @type: Join
## @args: [keys1 = keys1, keys2 = keys2, keys3 = keys3]
## @return: join3
## @inputs: [frame1 = datasource0, frame2 = datasource1, frame3 = datasource2]

## @type: DataSink
## @args: [connection_type = "s3", connection_options = {"path": "s3://foobar/glue/parquet/"}, format = "parquet", transformation_ctx = "datasink3"]
## @return: datasink3
## @inputs: [frame = join3]

ちょっと思っていた(DataSink複数版の逆のイメージ)のとは違う感じのダイアグラムになりましたが、合っていますね。

少し複雑なパターン

今度は少し複雑にしてみます。2つのDataSourceをJOINして、そのJOINしたものと別のDataSourceを更にJOINしてDataSinkへ繋げてみます。

## @type: DataSource
## @args: [database = "cm-ootaka-daisuke", table_name = "sample_table", transformation_ctx = "datasource0"]
## @return: datasource0
## @inputs: []

## @type: DataSource
## @args: [database = "cm-ootaka-daisuke", table_name = "sample_table", transformation_ctx = "datasource1"]
## @return: datasource1
## @inputs: []

## @type: DataSource
## @args: [database = "cm-ootaka-daisuke", table_name = "sample_table", transformation_ctx = "datasource2"]
## @return: datasource2
## @inputs: []

## @type: Join
## @args: [keys1 = keys1, keys2 = keys2]
## @return: join3
## @inputs: [frame1 = datasource0, frame2 = datasource1]

## @type: Join
## @args: [keys3 = keys3, keys4 = keys4]
## @return: join4
## @inputs: [frame1 = datasource2, frame2 = join3]

## @type: DataSink
## @args: [connection_type = "s3", connection_options = {"path": "s3://foobar/glue/parquet/"}, format = "parquet", transformation_ctx = "datasink5"]
## @return: datasink5
## @inputs: [frame = join4]

このパターンだとちょっとパッと見て分かるダイアグラムにするのは厳しいようです。複雑なパターンの場合には左右への配置が難しいのかもしれませんね。

まとめ

以上、スクリプト編集画面のダイアログを色々と試してみた結果でした。複雑なパターンになってしまうと少し可視化が難しそうでしたが、それでも可視化されているとジョブの流れが追い易いと思うので、積極的にコメントを記載していければと思います。

どなたかのお役に立てれば幸いです。それでは!