My AWS Glue ジョブが、大規模なデータセットを Amazon RDS から Amazon S3 に移行中、ノードが欠損し処理が失敗します。

最終更新日: 2020 年 9 月 4 日

AWS Glue を使い、Amazon Relational Database Service (Amazon RDS) あるいはオンプレミスの JDBC データベースから、Amazon Simple Storage Service (Amazon S3) に大規模なデータセットを移行しています。My ETL ジョブの処理に長い時間がかかり、その後、ノードの欠損で失敗します。

簡単な説明

AWS Glue は 1 つの接続でデータセット全体を読み込みます。大規模な JDBC テーブルを移行する場合、ETL ジョブは、 AWS Glue 側の進捗情報を得られないまま長期間にわたり処理しつづけます。そのためジョブは、ディスク容量不足 (ノード欠損) として処理に失敗します。この問題を解決するには、JDBC テーブルを並列で読み込むようにします。それでもノード欠損での処理失敗が解決しない場合は、SQL 式にプッシュダウン述語を使用します。

解決方法

JDBC データセットのノード欠損エラーを解決するには、次のいずれかの方法を使用します。

JDBC テーブルを並列で読み込む

テーブルに数値列 (INT または BIGINT) がない場合は、hashfield オプションでデータを分割します。JDBC テーブル内の列の名前に hashfield を設定します。最良の結果を得るには、値が均等に分散されている列を選択するようにします。

テーブルに数値列がある場合は、テーブル内に、もしくは DynamicFrame の作成中にhashpartitionshashexpression オプションを定義します。

  • hashpartitions は、データ読み込みを行うために AWS Glue が作成するタスクの数を定義します。
  • hashexpression は、タスク間で均等に行を分割します

JDBC 接続を使用して DynamicFrame を作成する間に、hashpartitionshashexpression の設定をする例を次に示します。connection_option で、JDBC URL、ユーザー名、パスワード、テーブル名、およびカラム名を置き換えます。

connection_option= {"url": "jdbc:mysql://mysql–instance1.123456789012.us-east-1.rds.amazonaws.com:3306/database", "user": "your_user_name", "password": "your_password","dbtable": "your_table","hashexpression":"column_name","hashpartitions":"10"}

datasource0 = glueContext.create_dynamic_frame.from_options('mysql',connection_options=connection_option,transformation_ctx = "datasource0")

AWS Glue カタログから DynamicFrame を作成する間に、hashpartitionshashexpression の設定をする例を次に示します。

datasource0 = glueContext.create_dynamic_frame.from_catalog(database = "your_database", table_name = "your_table",additional_options={"hashexpression":"column_name","hashpartitions":"10"}, transformation_ctx = "datasource0")

注: hashpartitions により大きな値を設定すると、テーブルのパフォーマンスが低下する場合があります。これは、各タスクがテーブル全体を読み込み、複数行をまとめてエグゼキュータに返すからです。

詳細については、「JDBC テーブルからの並列読み取り」をご参照ください。

SQL 式でプッシュダウン述語を使用する

注意: 次の SQL 式は、Oracle データベースのプッシュダウン述語としては機能しません。ただし、この式は、AWS Glue (Amazon Aurora、MariaDB、Microsoft SQL Server、MySQL、PostgreSQL) でネイティブにサポートされている他のすべてのデータベースのプッシュダウン述語としては機能します。

hashpartitionshashexpression の設定を行っても、テーブルに数十億のレコードやテビバイト (TiB) 級のデータが含まれている場合は、ジョブの処理完了に長い時間がかかったり、ノード欠損で失敗することがあります。これらの問題を解決するには、 hashexpression オプションを使い SQL 式を次のようにします。

column_name > 1000 AND column_name < 2000 AND column_name

SQL 式は プッシュダウン述語として機能し、ジョブは一度にすべてのデータを読み込まず、強制的に 1 回の実行で 1 行のセットを読み込むようになります。完全なステートメントの例を示します。

datasource0 = glueContext.create_dynamic_frame.from_catalog(database = "sampledb", table_name = "test_table",additional_options={"hashexpression":"column_name > 1000 AND column_name < 2000 AND column_name","hashpartitions":"10"}, transformation_ctx = "datasource0")

注: この設定で最初にジョブを実行する際は、 ジョブブックマークを無効にしていることを確認してください。ジョブブックマークを使いジョブを実行すると、AWS Glue では列の最大値だけ記録します。ジョブを再度実行しても、以前のブックマークより大きい値を含む行のみが、AWS Glue で処理されます。必要な場合は、最終ジョブの実行中であっても、ジョブブックマークを有効にすることができます。