例のAWSデータレイクの本でお勉強がてら AWS Glueを開いていたら何やら「new!」としてAWS Glue Studioなる機能が追加されていたので実際に触ってみました。
一言でいうと「AWS Glueの新しいビジュアルインタフェースで、利用者がAWS Glue ETL ジョブを簡単に作成、実行、および監視できるようになるもの」だそうです。
実際に簡単なCSVのサンプルデータを作ってどんな感じに利用出来るのか試してみたので自分へのメモを兼ねて残します。 今回は実際の現場でよくあるであろう複数テーブルのジョインや、不要カラムの削除、カラム名変更、フィルタリングをやってみました。
サンプル環境整備
今回用意したサンプルデータは以下2点のごく簡単なものです。 最終的にこのデータ2つに上で書いたようなETLをかけてデータ分析用途のファイルとして出力してみます。
サンプルデータ
% cat /tmp/one.csv <(echo -----) /tmp/two.csv No,aaa,bbb,ccc,ddd 1,a1,b1,c1,d1 2,a2,b2,c2,d2 3,a3,b3,c3,d3 4,a4,b4,c4,d4 5,a5,b5,c5,d5 ----- No,eee,fff,ggg,hhh 1,e1,f1,g1,h1 2,e2,f2,g2,h2 3,e3,f3,g3,h3 4,e4,f4,g4,h4 5,e5,f5,g5,h5 %
まずは、こちらの2つのサンプルデータを 検証用S3bucket任意の名前(私の場合は ytamu-aws-glue-xxx)でを作成してぶち込みます。
% aws s3 mb s3://ytamu-aws-glue-src #インプット用(データレイクでいうRawデータ格納用) % aws s3 mb s3://ytamu-aws-glue-dst #アウトプット用(データレイクでいうETL後のデータ格納用) % aws s3 cp /tmp/one.csv s3://ytamu-aws-glue-src/ % aws s3 cp /tmp/two.csv s3://ytamu-aws-glue-src/
IAM-Roleとして、GlueServiceRole(名称はお好みで) を作成します。
信頼されたエンティティの種類は Glue(glue.amazonaws.com)とし、IAMポリシーとして以下2点をアタッチしておきます。(検証環境でなければ必要に応じて絞るべきですが)
・AmazonS3FullAccess
・AWSGlueServiceRole
AWS Glueでデータカタログ用のデータベースを作成します。
% aws glue create-database --database-input Name=ytamu-test-db,Description=hoge
続けてCrawlerを作成します。(nameとdatabaseの名称は適当に指定で)
% aws glue create-crawler --name ytamu-test-crawler --database ytamu-test-db --role GlueServiceRole --targets '{"S3Targets":[{"Path":"s3://ytamu-aws-glue-src/"}]}'
上で作成したCrawlerを実行しデータカタログを作ります。虫が苦手な方もAWS CLIでやれば大丈夫です。
% aws glue start-crawler --name ytamu-test-crawler
処理が終わる(RUNNING->Readyになる)まで待ちます。(45sec程度でした)
% aws glue get-crawler --name ytamu-test-crawler |grep State
あっという間に出来ましたね。Apache Hive Metastore互換のデータカタログが。<-すごい
中を覗いてみると、きちんとサンプルデータのone.csvの内容通りレコードの行数やらデリミタやらカラムやらデータ型やら平均レコードサイズなど様々な情報が取得されデータカタログが出来上がっているのがわかります。
(一部手でフィルタリングしてます)
% aws glue get-table --database-name ytamu-test-db --name one_csv { "Table": { "Name": "one_csv", "DatabaseName": "ytamu-test-db", "Owner": "owner", "CreateTime": 1601994226.0, "UpdateTime": 1601994226.0, "LastAccessTime": 1601994226.0, "Retention": 0, "StorageDescriptor": { "Columns": [ { "Name": "no", "Type": "bigint" }, { "Name": "aaa", "Type": "string" }, { "Name": "bbb", "Type": "string" }, { "Name": "ccc", "Type": "string" }, { "Name": "ddd", "Type": "string" } ], "Location": "s3://ytamu-aws-glue-src/one.csv", "InputFormat": "org.apache.hadoop.mapred.TextInputFormat", "OutputFormat": "org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat", "Compressed": false, "NumberOfBuckets": -1, "SerdeInfo": { "SerializationLibrary": "org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe", "Parameters": { "field.delim": "," } }, "BucketColumns": [], "SortColumns": [], "Parameters": { "CrawlerSchemaDeserializerVersion": "1.0", "CrawlerSchemaSerializerVersion": "1.0", "UPDATED_BY_CRAWLER": "ytamu-test-crawler", "areColumnsQuoted": "false", "averageRecordSize": "14", "classification": "csv", "columnsOrdered": "true", "compressionType": "none", "delimiter": ",", "recordCount": "6", "sizeKey": "89", "skip.header.line.count": "1", "typeOfData": "file" }, "StoredAsSubDirectories": false }, "PartitionKeys": [], "TableType": "EXTERNAL_TABLE", "Parameters": { "CrawlerSchemaDeserializerVersion": "1.0", "CrawlerSchemaSerializerVersion": "1.0", "UPDATED_BY_CRAWLER": "ytamu-test-crawler", "areColumnsQuoted": "false", "averageRecordSize": "14", "classification": "csv", "columnsOrdered": "true", "compressionType": "none", "delimiter": ",", "recordCount": "6", "sizeKey": "89", "skip.header.line.count": "1", "typeOfData": "file" }, "CreatedBy": "arn:aws:sts::XXXXXXXXXXX:assumed-role/GlueServiceRole/AWS-Crawler", "IsRegisteredWithLakeFormation": false } } %
AWS Glue Studio
ここから本題の AWS Glue Studioのお話ですが、GUIがウリの機能なので画面キャプチャーを取るのが面倒ですがAWSマネジメントコンソールに画面を移して作業します。
AWS -> AWS Glue -> 左ペインの AWS Glue Studioを開きます。
ジョブ作成画面に遷移したら、Create jobのラジオボタンをお好みで選択し [Create]を押下します。 今回は S3 -ETL-> S3がしたいので画面のように S3 -> S3を選択しました。
上の画面内にも書いてある通り、ここはVisual画面を空の状態で作るかそれともソースとターゲットのノードを選択追加した状態で作るかを選ぶだけです。ソースは、S3、RDS、Kinesis、Kafka(のGlueのデータカタログ)が選べ、ターゲットの方は S3バケットかGlueのデータカタログが選べます。
仮に Blank graphを選択しても、空のVisual画面で始まるだけでその後数クリックでソースとターゲットを指定した内容と同じ状況は作れますし、ソースとターゲットの指定を間違えてても後に数クリックで変更可能です。 (という訳でここのラジオボタンの選択はあまり気にせずいきましょう)
S3 -> S3 を選択して[Create]した場合の初期のVisual画面はこんな感じです。 指定どおりSourceとTargetのノードが S3 bucketになっている事がわかります。 真ん中にはTransform のノードも空の状態で1つ作成してくれます。
ここからGUIでぽちぽちして処理を作っていきます。 私の場合、マニュアルを読まずに触っちゃうタイプの人間なので操作感を掴むまで多少戸惑いましたが これから触る方は以下のポイントだけ事前に頭に入れておくとスムーズに操作が出来ると思います。
ノードの追加
水色の+マークでノードを追加できる
・何も選択していない状態で+を押下したらスタート地点のノードが追加される
・何かノードを選択した状態で+を押下したらそのノードの下に次の処理の空ノードが追加される
・既に子のノードが存在している親ノードを選択した状態で+を押下するとそこを起点とした2分岐にできるノードの削除
ノードを選択した状態で 赤いxマークを押下すると選択しているノードを削除できるノードの移動
ノードを選択した状態で右ペインの Node Properties にある Node parents を選択し切り替える事でそのノードがどのノードと線で繋がるか(連携するか)を変更できる
1つめの起点としてData Source(S3バケット) に one.csv のデータカタログを指定します。 画面の通り、Data Sourceのノードを選択し、右ペインの Data source properties - S3 からone_csvを選択。
2つめの起点として、何もノードを選択していない状態で +マークを押下すると空ノードが作成されます。
その空ノードが選択された状態で、Node Type のプルダウンから Data Sourceとして S3 を選択します。
(GUI力の高い方はこちらの画面を見た瞬間わかったかもしれませんが、仮に初期のラジオボタンの種類選択を誤ってもここの選択を切り替えるだけで解決します)
同様にS3 にある two.csv のデータカタログを指定していきます。
変換処理(Transform)
今回はサンプルデータ2つを起点とし、ETLのTの字にあたるTransformを4点やってみました。
- 複数テーブルのジョイン
- 不要なカラムの削除
- カラム名変更
- フィルタリング(カラム内の条件を満たすデータのみ出力)
これ以外の組み込み処理に興味がある場合は、以下オフィシャルサイトの情報を参照ください。 組み込み変換 - AWS Glue
やること1.複数テーブルのジョイン
分析のために、異なるデータを繋ぎ合わせるようなケースがあると思うので実施してみます。 今回S3バケット内に格納されている、2つのサンプルデータを1つに纏める為には、TransformのJoinを使います。
Joinのように複数のデータソースが必要な場合は、選択をした時点で「ここは複数指定が必須ですよ」と警告の赤いエクスクラメーションマークが出ますので、追加したtwo.csvの方の S3のデータカタログにもチェックを入れて指定します。
すると、フローが以下のように複数のデータソース(S3バケット)から TransformのJoinのノードに線が繋がります。 わかりやすいですね。
ここまでは、ただデータソースを指定しただけなので、これからJoinの処理の詳細を指定していきます。 Transformタブを押下し、Join Typeや Join Conditions を指定します。 今回は適当に Inner joinでお互いのnoカラムを指定しました。
この時、Transformタブの隣にある Output schema タブを選択することで このTransform処理を加えることでどうなるのか?を確認することができます。
この先Transform処理を複数つなげていきますが、各処理のノード毎にこのような確認が可能なのでとても便利ですね。
今回は図のように2テーブルをジョインした想定のカラムが表示されている事や、重複している no カラムの頭にドットを自動付与してくれている事がわかります。
続けて次のTransformの処理を作っていきます。 という事で、先程作ったJoinのノードを選択し、+ボタンでポチっとノードを追加すると以下画面のように分岐してしまいます。(下にノードが既にある場合にこの挙動は仕様です)
今回は、間にTransformを順に追加していきたいイメージだったので、ちょっと違う・・・って気分になりますが こういう状態になった場合は、一番下にしたいノード(今回はデータターゲットのS3)を選択し、Node Propertiesタブ -> Node parents で今回の場合はぶら下げたい(親にしたい)ノードにチェックを入れます。
そうすると今回思い描いていたフロー図になってホッとします。後は空ノードを好きな処理に変えていくといった具合です。
(GUI力の高い方はこちらの流れを見た瞬間、沢山の処理を作る際はターゲットを最後に作ったほうが良くない?というかBlank graphスタートでよくない?と思ったかもしれませんが、私もその通りだと思います)
やること2.不要なカラムの削除
データをマージした後、例えば内容が重複していたり、値が入っていない or 入っててもゴミのような不要カラムがあった場合を想定し特定カラムを除外してみます。
今回は、Transformの DropFields を利用することで、「bbb」,「fff」,「.no」カラムをチェックして除外してみました。
カラム名変更しつつdropチェックも出来るような ApplyMapping や 逆に出力したいカラムを選択する SelectFields というTransformを選択しても同様の処理は実現出来ます。
やること3.カラム名変更
分析用途によりカラム名を変更する場合があると思うのでソースのカラム名「hhh」を「iii」に変更してみます。
RenameField を使って Source path に「hhh」カラムを選択、Traget path はフリーで自分の好きな文字列を入力(今回はiii)としました。
やること4.フィルタリング
対象データを一部をフィルタリングします。例えば日付がYYYYMMDD以降のみのデータとかに絞る場合等はよくあると思うので今回はNo.カラムの値が3以上のものに絞って出力するようにしました。
出力先指定と実行
最後にアウトプット先の S3バケットの指定とフォーマットの指定をします。 今回はデータ解析系の検証っぽく Apache Parquet形式を指定してみました。
(ずっと画面でS3のノードに警告が出ていて気になっていた方=多分エンジニアがいたかもしれませんが、単純にS3バケットのURIを指定していなかったからというだけで、指定したら消えます)
ここまでが今回の処理の全体の図となり、GUIのポチポチだけで作ってきましたが、 Scriptカラムを選択することで実際に走行するコード(今回は PySpark)を確認する事ができます。
処理を実行する前に、ジョブの名前(アカウント内で一意のもの)や実行する際のIAMロールを 指定する必要があるので、Job details カラムを選択して指定します。
処理を実行前に一度保存する必要があるので[Save]をしてから[Run]を押下し、実行します。
もし、実行するにあたり問題(設定の不備/不足)がある場合は、 赤いエクスクラメーションマークで当該ノードの箇所に警告を出してくれるので適宜見直します。
AWS Glue Studioではモニタリングとして以下のような画面も追加されており、グラフィカルに処理の状況を把握可能です。
また、Run detailsタブを押下することで過去のジョブの実行履歴やログも確認できます。 (各ログのリンクを押下すると CloudWatch Logs の当該ログ画面に遷移します)
アウトプットの確認
処理が終わったら出力先に指定した S3バケットにデータが吐かれている事を確認します。(今回は1min程度でした)
出力形式でApache Parquetを指定すると自動的にsnappyで圧縮もしてくれるようです。
% aws s3 ls s3://ytamu-aws-glue-dst/ 2020-10-07 18:58:15 719 part-00000-e506ff91-52b6-4eca-958c-e84c956bea23-c000.snappy.parquet 2020-10-07 18:58:17 1544 part-00051-e506ff91-52b6-4eca-958c-e84c956bea23-c000.snappy.parquet 2020-10-07 18:58:17 1544 part-00052-e506ff91-52b6-4eca-958c-e84c956bea23-c000.snappy.parquet 2020-10-07 18:58:15 1544 part-00053-e506ff91-52b6-4eca-958c-e84c956bea23-c000.snappy.parquet %
対象ファイルをダウンロードして parquet-tools を利用し参照したところ 想定どおりのETLを経たアウトプットが得られている事が確認出来ました :tada:
一部データを参照すると以下の様な感じです。 (Amazon S3標準の S3 Selectを利用しても同様に Parquet形式を指定する事で参照可能です)
% parquet-tools cat part-00051-e506ff91-52b6-4eca-958c-e84c956bea23-c000.snappy.parquet ccc = c3 aaa = a3 no = 3 ggg = g3 iii = h3 eee = e3 ddd = d3 %
本番データであれば、この後にAmazon Redshiftでロードしてクエリ投げて分析したり、Amazon QuickSightと連携しグラフで可視化するとかの用途で活用出来ると思います。
という訳で今回、AWS Glue Studioを少し触ってみました。 GUIでフロー図や各Transform処理単位でOutput Schema機能で各処理でどのような項目が出力されるか等を確認しながら処理を作り込めるのは便利で、利用にあたり敷居が下がった印象です。
まとめ
ちょっとだけAWS Glueを身近に感じました。