Spark履歴サーバ(Spark UI)をDockerで立ち上げて、Glue Sparkジョブ実行の結果を確認してみた

Glue Sparkジョブの実行履歴をローカルDocker上のSpark UIで確認する方法を試してみました。

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

こんにちは、nkhrです。

Glue Sparkジョブの実行履歴をローカルDocker上のSpark UIで確認する方法を試してみました。

DockerによるSpark履歴サーバ起動

起動・設定方法は公式ドキュメントがあります。EC2サーバで起動するCloudformationテンプレートと、Dockerで起動するDockerfile/pom.xmlファイルが利用できます。今回は、Dockerfileを利用しました。

Glue Job設定のSpark UI Logs有効化

Glueジョブの詳細設定で、Spark UIで表示するためのログ出力を有効にします。指定したS3パスにログが出力されます。

上図のチェックボックスをONにします。内部的にはSpark設定の「spark.eventLog.enabled」がtureになります。(デフォルトfalse)

Spark UIサーバ起動

コマンドの実行環境は「Windows 10 Pro」、「Powershell 7」です。

  1. 対象バージョンのDockerfileとpom.xmlをローカルに取得(今回はGlue3.0)
  2. ダウンロードしたファイルの格納フォルダに移動し、Docker buildコマンドを実行
    $ cd <path to download files>
    $ docker build -t glue/sparkui:latest .

  3. AWS認証情報を取得(スキップ可能)

    今回の検証では、MFA認証ありのSwitch Roleでログ格納先のS3にアクセスするため、STSでSession Tokenを取得(Switch Roleの場合はSession時間は最大1時間)

    > aws sts assume-role --role-arn arn:aws:iam::<account-id>:role/<swich-role-name> --role-session-name "RoleSession1" --profile <profilename> > assume-role-output.txt
        
    > cat .\assume-role-output.txt | jq -r .Credentials.AccessKeyId
    > cat .\assume-role-output.txt | jq -r .Credentials.SecretAccessKey
    > cat .\assume-role-output.txt | jq -r .Credentials.SessionToken

    jqコマンドの「-r(-raw-output)」オプションは、ダブルクォーテーションを消すために利用しています。

  4. 以下のコマンドでSpark UIのサーバを立ち上げ、S3に出力されたログをSpark UIで参照します。前回立ち上げたDockerコンテナが残っている場合は、手順6.に記載のコンテナの停止と削除を先に実行します。

    > docker run --name sparkui-logs -itd -e SPARK_HISTORY_OPTS="$SPARK_HISTORY_OPTS -Dspark.history.fs.logDirectory=s3a://<spark-ui log output path> ` 
    -Dspark.hadoop.fs.s3a.access.key=$(cat .\assume-role-output.txt | jq -r .Credentials.AccessKeyId) ` 
    -Dspark.hadoop.fs.s3a.secret.key=$(cat .\assume-role-output.txt | jq -r .Credentials.SecretAccessKey) ` 
    -Dspark.hadoop.fs.s3a.session.token=$(cat .\assume-role-output.txt | jq -r .Credentials.SessionToken) ` 
    -Dspark.hadoop.fs.s3a.aws.credentials.provider=org.apache.hadoop.fs.s3a.TemporaryAWSCredentialsProvider" -p 18080:18080 glue/sparkui:latest "/opt/spark/bin/spark-class org.apache.spark.deploy.history.HistoryServer"

  5. Spark UIに接続

    http://localhost:18080

    ログ出力フォルダ設定は正しいかの確認メッセージがでるので、 「Show imcomplete applications」リンクをクリックして表示

  6. Dockerコンテナを削除(Spark UIログ確認の完了後)

    nameを「sparkui-logs」でコンテナ起動しているため、nameでフィルターしてコンテナIDを検索
     -f: フィルター設定
     -a: 停止済みのコンテナもすべて表示
     -q: コンテナIDのみ表示
        
    > docker stop $(docker ps -aq --filter "name=sparkui-logs")
    > docker rm $(docker ps -aq --filter "name=sparkui-logs")

Spark UIログの確認

以下の画面からジョブを選んで実行結果を参照します。

App Nameは、SparkContextのパラメータ「appName」で任意の名前を指定できます。複数ジョブを同じS3パスに出力する場合は、名前を設定しておくとよいと思います。

実行結果の表示

Jobタブの表示

DriverやWorker内のExecutor追加タイミングや、ジョブが時系列で表示できます。

上図では、1つのDriverとExecutorが追加され、Job 2では9秒(Duration)で6つのTaskを完了したことがわかります。

Stageタブの表示

ステージの実行結果が確認できます。ステージ数や、各ステージの実行時間(Duration)、スキャンしたデータ量(Input)、シャッフル時のデータの読み書き量(Shuffle Read/Write)などを確認できます。

Stage単位での表示

Descriptionのリンクをクリックすると、各ステージの詳細画面を表示できます。ステージ内のタスク数、実行タイムライン、DAG(DAG Visualizationのリンクをクリックして表示)などが表示できます。

Environmentタブの表示

Environmentタブは、実行で利用されたSpark設定の一覧が表示できます。ブロックサイズの設定など、最適化のためのパラメータ値を確認できます。

SQLタブの表示

Spark SQLを使い、Glueジョブの加工を行っている場合は、SQLタブの表示が参考になると思います。クエリのDAGや、実行プランを確認することができます。

最後に

Spark UI用のログは約30秒間隔で出力されるため、Glueジョブ実行中もSpark UIで実行状況を確認できます(たとえばTotal Taskのうち、どれくらい完了しているかなど)。処理が長いジョブはSpark UIで状況を確認してみてもよいかもしれません。

以上、nkhrでした。

参考資料