Amazon EMR の Spark で「デバイスの容量に空きがありません」というステージ障害を解決するには、どうすれば良いですか?

最終更新日: 2020 年 1 月 8 日

Apache Spark アプリケーションを Amazon EMR クラスターに送信しました。アプリケーションは、次のような「デバイスの容量に空きがありません」というステージ障害で失敗しました。

Job aborted due to stage failure: Task 31 in stage 8.0 failed 4 times, most recent failure: Lost task 31.3 in stage 8.0 (TID 2036, ip-xxx-xxx-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 : No space left on device

簡単な説明

Spark は、コアノードおよびタスクノードのローカルディスクを使用して中間データを保存します。ディスク容量が不足すると、ジョブは「デバイスの容量に空きがありません」というエラーで失敗します。このエラーを解決するには、次のいずれかの方法を使用します。

  • Amazon Elastic Block Store (Amazon EBS) の容量を追加する。
  • Spark パーティションを追加する。
  • ブートストラップアクションを使用して、コアノードおよびタスクノードのストレージを動的にスケールアップする。詳細および推奨ブートストラップアクションスクリプトについては、Dynamically scale up storage on Amazon EMR clusters を参照してください。

解決方法

EBS 容量を追加する

新しいクラスターの場合: より大型の EBS ボリュームを使用する

Amazon EMR クラスターを起動し、より大型の EBS ボリュームを持つ Amazon Elastic Compute Cloud (Amazon EC2) インスタンスタイプを選択します。各インスタンスタイプに割り当てられたストレージの量とボリューム数の詳細については、「インスタンスのデフォルト 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.xmlyarn.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)