扱うデータ量を増やすとGlue JobがCommand Failed with Exit Code 10.
で失敗する事象に遭遇したため内容を記載致します。
まとめ
- Glue Jobワーカー1つのメモリ上に乗り切らないデータを処理している可能性がある
- データをメモリに読み込む部分の実装をSparkに変更することで改善される可能性がある
以下、詳細です。
原因
Glue Jobワーカー1つのメモリ上に乗り切らないデータを処理している可能性があります。
特に、次のような事象に合致している場合は、メモリに乗り切らないデータを処理している可能性が高いです。
- 扱うデータ量を減らすと改善する
- Sparkイベントログ(※1)が出力されていない
glue.XX.jvm.heap.usage
(※2)が上昇していない
※1 モニタリングオプションのSpark UI
を有効化するとS3に出力されるファイルのことを指します。
Spark UI を有効にすると、 AWS Glue ETL ジョブと、 AWS Glue 開発エンドポイントの Spark アプリケーションの Spark イベントログを Amazon Simple Storage Service (Amazon S3) の指定個所に保持できます。
AWS Glue ジョブ用の Apache Spark ウェブ UI の有効化
※2 GlueのCloudWatchメトリクスのことを指します。
Amazon CloudWatch を使用して AWS Glue をモニタリングすることで、AWS Glue から raw データを収集し、リアルタイムに近い読み取り可能なメトリクスに加工することができます。これらの統計は 2 週間記録されるため、履歴情報にアクセスしてウェブアプリケーションまたはサービスの動作をより的確に把握することができます。デフォルトでは、AWS Glue メトリクスデータは CloudWatch に自動的に送信されます。
Amazon CloudWatch によるモニタリング
対応
メモリにデータを読み込んでいる処理の具体的な実装を確認し、それがSparkでの実装でない場合は、Sparkに書き換えることで改善する可能性があります。
1つのワーカーのメモリに乗り切らない場合でも、Sparkはデータを分割して複数のワーカー扱うことができるためです。
私が当該の問題に直面したケースではAWS Data Wrangler(Pandasの拡張ライブラリ)を利用していました。ライブラリのメソッドが内部的にPandasでS3のParquetファイルを全て読み込むような実装をしていたため、1つのワーカーに乗り切らずに失敗していた形です。
AWS Data Wrangler(Pandas)での実装をやめて、当該処理をSparkによる処理に変更したところ、改善しました。
なお、Glueのワーカー1つに乗り切らないことで発生していたため、単純にワーカー数を倍々で増やしていっても解決しませんでした。
備考
恐らく、本記事と同じ原因のため、つまり、1つのワーカーのメモリ上にデータが乗り切らないため失敗しているケースがフォーラムで報告されています。
Hello,
I have a .sql.gz file (~50gb) on S3 – I’m attempting to download it, unzip it, and upload the decompressed contents back to S3 (as .sql).
The Glue job is able to successfully decompress/upload smaller files (largest I’ve tested is ~1gb).
However, whenever I attempt to process the larger ~50gb file I get back the following error:
“Command failed with exit code 10”
Glue job failing with exit code 10 (unable to decompress ~50gb file on S3)
執筆時点で明確な答えは出ていませんが、フォーラム投稿者の下記コードを見る限り、BytesIO部分でインメモリの実装をしているため発生しているものと推察致します。
import boto3
from io import BytesIO
import gzip
s3_bucket_name = 'some-bucket'
stage_s3_key_prefix = 'prefix/to/stage'
source_s3_key = f'{stage_s3_key_prefix}/somefile.sql.gz'
target_s3_key = f'{stage_s3_key_prefix}/somefile.sql'
s3_client = boto3.client('s3')
s3_client.upload_fileobj(
Fileobj=gzip.GzipFile(
None,
'rb',
fileobj=BytesIO(
s3_client.get_object(
Bucket=s3_bucket_name,
Key=source_s3_key
// line below should be: body.read()
// I cant index Body b/c this markdown will display a URL instead
).read()
)
),
Bucket=s3_bucket_name,
Key=target_s3_key
)
BytesIO はインメモリーのバイナリストリームです
io — ストリームを扱うコアツール
また、今回の記事とは別の原因とはなりますが、同じPythonライブラリを2回インポートした結果、同じようなエラーとなると言ったような報告もあります。
On my Glue job, I got this error when I imported the same external python library twice. Removing the duplicate library from the job parameter ‘Python lib path’ worked for me and the job runs now.
Glue job failing with exit code 10 (unable to decompress ~50gb file on S3)
こういった事象を鑑みると、データがメモリに乗り切らない場合や、何らかの理由でGlue Jobを開始できなかった際に、当該エラーが出るのかもしれません。
メッセージから原因の推察を行うのが難しいエラーですが、少しでもご参考になれば幸いです。
コメント