Apache Spark アプリケーションを Amazon EMR クラスターに送信しました。アプリケーションは、次のような「デバイスの容量に空きがありません」というステージ障害で失敗しました。
ステージの障害によりジョブが中断されました: ステージ 8.0 のタスク 31 が 4 回失敗しました。最新の失敗: ステージ 8.0 でタスク 31.3 が失われました (TID 2036、ip-xxx-xxx-xx-xx-xxx.compute.internal、executor 139): org.apache.spark.memory. SparkOutOfMemoryError: error while calling spill() on org.apache.spark.util.collection.unsafe.sort.UnsafeExternalSorter@1a698b89 : デバイスに空き容量が残っていません
簡単な説明
Spark は、コアノードおよびタスクノードのローカルディスクを使用して中間データを保存します。ディスク容量が不足すると、ジョブは失敗し「デバイスの容量に空きがありません」というエラーを表示します。このエラーを解決するには、次のいずれかの方法を使用します。
- Amazon Elastic Block Store (Amazon EBS) の容量を追加する。
- Spark パーティションを追加する。
- ブートストラップアクションを使用して、コアノードおよびタスクノードのストレージを動的にスケールアップする。詳細およびブートストラップアクションの例については、「Amazon EMR クラスターのストレージを動的にスケールアップする」を参照してください。
解決方法
EBS 容量を追加する
新しいクラスターの場合: より大型の EBS ボリュームを使用する
Amazon EMR クラスターを起動し、EBS ボリュームがより大型の Amazon Elastic Compute Cloud (Amazon EC2) インスタンスタイプを選択します。各インスタンスタイプに割り当てられたストレージの量とボリューム数の詳細については、「インスタンスのデフォルト Amazon EBS ストレージ」を参照してください。
実行中のクラスターの場合: EBS ボリュームをさらに追加する
1. EBS ボリュームを増やしても問題が解決しない場合は、コアノードとタスクノードに EBS ボリュームをさらに添付します。
2. 添付したボリュームをフォーマットしてマウントします。必ず、正しいディスク番号を使用します(/data の代わりに /mnt1 または /mnt2 など)。
3. SSH を使用してノードに接続します。
4. /mnt2/yarn ディレクトリを作成し、ディレクトリの所有者を YARN ユーザーに設定します。
sudo mkdir /mnt2/yarn
chown yarn:yarn /mnt2/yarn
5. /mnt2/yarn ディレクトリを /etc/hadoop/conf/yarn-site.xml の yarn.nodemanager.local-dirs プロパティ内に追加します。例:
<property>
<name>yarn.nodemanager.local-dirs</name>
<value>/mnt/yarn,/mnt1/yarn,/mnt2/yarn</value>
</property>
6. NodeManager サービスを再起動します。
sudo stop hadoop-yarn-nodemanager
sudo start hadoop-yarn-nodemanager
Spark パーティションを追加する
クラスター内のコアノード数およびタスクノード数に応じて、Spark パーティションの数を増やすことを検討してください。Spark パーティションを追加するには、次の Scala コードを使用します。
val numPartitions = 500
val newDF = df.repartition(numPartitions)
関連情報
Amazon EMR で Spark ジョブのステージ失敗をトラブルシューティングするにはどうすればよいですか?