Amazon EMR で Hive クエリ結果を出力する際に発生する Hive Java ヒープスペースの例外「OutOfMemoryError」の解決方法を教えてください。
最終更新日: 2020 年 5 月 18 日
Amazon EMR で Apache Hive クエリを実行していて、Hive はクエリ結果の出力中に OutOfMemoryError 例外をスローします。どうすればこのエラーを解決できますか?
簡単な説明
OutOfMemoryError 例外は、通常、INSERT OVERWRITE コマンド中に、hive-server2、Hive メタストア、またはクライアント側に十分なヒープスペースがない場合に発生します。この問題を解決するには、JVM の最大メモリ割り当てを増やすか、HADOOP_HEAPSIZE を増やします。
解決方法
OutOfMemoryError 例外を解決するには、以下のソリューションをご使用ください。
注: この解決方法では、Apache Tez コンテナメモリのチューニング中に発生する OutOfMemoryError 例外は対象外です。
JVM の最大メモリ割り当てを増加する
Hive シェルを起動すると、デフォルトで 1 GB のメモリが割り当てられます。最大メモリ割り当ては、-Xmx パラメータで定義されます。プロセスが最大値を超える値を使用しようとすると、Hive はプロセスを強制終了し、OutOfMemoryError 例外をスローします。この問題を解決するには、Hive シェルスクリプト (MB 単位) の -Xmx 値を増やしてから、Hive クエリを再度実行します。
HADOOP_HEAPSIZE を増やす
/mnt/var/log/hive/user/hadoop/hive.log に次のエラーがないか確認します。
# java.lang.OutOfMemoryError: Java heap space
# -XX:OnOutOfMemoryError="kill -9 %p"
# Executing /bin/sh -c "kill -9 12345"...
Killed
このエラーメッセージが表示された場合、JVM ヒープスペースのメモリが不足しています。次の例に示すように、/etc/hive/conf/hive-env.sh の Hive CLI サービスの HADOOP_HEAPSIZE を増やします。デフォルト値は 1000 です。ユースケースに応じて増やします。次に、Hive クエリを再度実行します。
export HADOOP_HEAPSIZE=2000
重要: この設定は、サービスの再起動後に hive-server2、Hive メタストア、および Hive CLI に適用されます。必要の応じて、これらのサービスごとに個別の値を設定できます。
Beeline または SQL Workbench/J
1. Beeline または SQL Workbench/J から同じクエリを実行している場合は、/mnt/var/log/hive/hive-server2.log および hive-server2.out をチェックして、ヒープスペースガベージコレクションエラーがないか確認します。例:
Transaction isolation: TRANSACTION_REPEATABLE_READ
0: jdbc:hive2://emr-analytics_master.abc.aws.> select id, name, x.* from mydb.location a, curated_admin.nxpepnd1_tpn_prvdr_pra_fclt b, curated_admin.test_table c where a.test = b._id and a._id = b._id and b._prod_id = c.prod_f_id;
#
# java.lang.OutOfMemoryError: Java heap space
# -XX:OnOutOfMemoryError="kill -9 %p"
# Executing /bin/sh -c "kill -9 27745"...
Killed
2. このようなエラーが見つかった場合は、/etc/hive/conf/hive-env.sh の hive-server2 の HADOOP_HEAPSIZE を増やします。この設定は、Hive メタストアと Hive クライアントにも適用されます。
export HADOOP_HEAPSIZE=2048
必要に応じて、条件ステートメントを使用して、hive-server2、メタストア、およびクライアントに異なるヒープサイズを指定します。例:
export HIVE_CLIENT_HEAPSIZE=1024
export HIVE_METASTORE_HEAPSIZE=2048
export HIVE_SERVER2_HEAPSIZE=3072
if [ "$SERVICE" = "metastore" ]
then
export HADOOP_HEAPSIZE=$HIVE_METASTORE_HEAPSIZE
elif [ "$SERVICE" = "hiveserver2" ]
then
export HADOOP_HEAPSIZE=$HIVE_SERVER2_HEAPSIZE
export HADOOP_OPTS="$HADOOP_OPTS -server -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/var/log/hive"
else
export HADOOP_HEAPSIZE=$HIVE_CLIENT_HEAPSIZE
fi
3. これらの設定を更新した後、Hive クエリを再度実行します。引き続き OutOfMemoryError 例外が発生し、同時に複数のクライアントを実行している場合は、ステップ 4 に進みます。引き続き OutOfMemoryError 例外が発生し、同時に複数のクライアントを実行していない場合は、ステップ 8 に進みます。
4. ユースケースに応じて、クライアントごとに -Xmx パラメータを増やします。
5. 次の例に示すように、HADOOP_OPTS 行に -XX:+UseParNewGC (新しい並列ガベージコレクタ) または -XX:+UseConcMarkSweepGC (同時マークスイープガベージコレクタ) を追加して、ユースケースに適したガベージコレクタを選択します。ガベージコレクタの選択の詳細については、Java ドキュメントのガベージコレクションおよび Java HotSpot VM オプションをご参照ください。
export HADOOP_HEAPSIZE=2048
if [ "$SERVICE" = "cli" ]; then
if [ -z "$DEBUG" ]; then
export HADOOP_OPTS="$HADOOP_OPTS -XX:NewRatio=12 -Xmx12288m -Xms10m -XX:MaxHeapFreeRatio=40 -XX:MinHeapFreeRatio=15 -XX:+useParNewGC -XX:-useGCOverheadLimit"
else
export HADOOP_OPTS="$HADOOP_OPTS -XX:NewRatio=12 -Xmx12288m -Xms10m -XX:MaxHeapFreeRatio=40 -XX:MinHeapFreeRatio=15 -XX:-useGCOverheadLimit"
fi
fi
6. 指定された時間内にガベージコレクションが成功しなかった場合、Hive は OutOfMemoryError 例外をスローします。制限時間を削除するには、-XX:-UseGCOverheadLimit を削除するか、-XX:+UseGCOverheadLimit に置き換えます。必要に応じて、 -XX:-UseGCOverheadLimit を変更して、ガベージコレクションの新しい時間制限を指定します。詳細については、Java ドキュメントの並列コレクターを参照してください。
7. Hive クエリを再度実行します。実行時に Hive がターミナルでヒープスペースエラーをスローし、hive.log または hive-server2.log にエラーがない場合は、Hive クライアントのメモリが不足している可能性があります。例:
Transaction isolation: TRANSACTION_REPEATABLE_READ
0: jdbc:hive2://emr-analytics_master.abc.aws.> select id, name, x.* from mydb.location a, curated_admin.nxpepnd1_tpn_prvdr_pra_fclt b, curated_admin.test_table c where a.test = b._id and a._id = b._id and b._prod_id = c.prod_f_id;
#
# java.lang.OutOfMemoryError: Java heap space
# -XX:OnOutOfMemoryError="kill -9 %p"
# Executing /bin/sh -c "kill -9 27745"...
Killed
8. このエラーを解決するには、クライアントメモリを増やしてから、クエリを再度実行します。
9. Hive が引き続き OutOfMemoryError 例外をスローする場合は、クライアントに対して次のステップを実行します。
Beeline:
デフォルトでは、Beeline は 出力関係全体をバッファしてから、stdoutに出力しようとします。この動作は、出力関係が大きい場合に OutOfMemoryError 例外を発生させ可能性があります。Beeline で OutOfMemoryError 例外を解決するには、次のコマンドを使用して Beeline を起動し、Hive クエリを再試行します。
beeline --incremental=true
SQL Workbench/J:
32 ビット Java ランタイム環境 (JRE) では、アプリケーションはデフォルトで最大 1 GB のメモリを使用できます。64 ビット JRE では、アプリケーションはデフォルトで使用可能な物理メモリの最大 65% を使用できます。アプリケーションで使用できるメモリの量を確認するには、[ヘルプ] を選択し、[バージョン情報] を選択します。
- macOS の場合は、必要に応じて Info.plist ファイルの -Xmx1024m 値を増やします。Info.plist は通常、/Applications/SQLWorkbenchJ2.app/Contents ディレクトリにあります。例えば、アプリケーションで使用できるメモリ容量を 2 倍にするには、その値を -Xmx1024m から -Xmx2048m に変更します。次に、クエリを再度実行します。
- Windows の場合は、INI ファイルを作成し、vm.heapsize.preferred パラメータを INI ファイルに追加して、アプリケーションで使用できるメモリの量を増やします。
シェルスクリプトまたはバッチスクリプトを使用している場合は、SQL Workbench/J をインストールするときに使用可能なメモリを増やすことができます。以下の例のコマンドは、インストール中に 3 GB の使用可能なメモリを作成します。
java -Xmx3g -jar sqlworkbench.jar
注: OutOfMemoryError 例外が hive-server2 や Hive CLI ではなくクライアント側にある場合は、出力を Amazon Simple Storage Service (Amazon S3) または HDFS に保存します。クエリの結果を表示するのに Beeline または SQL Workbench/J を使用しないでください。
Hive の再起動
hive-site.xml または hive-env.sh の Hive プロパティを変更した場合、更新された設定を有効にするには Hive を再起動する必要がある場合があります。
Amazon EMR リリースバージョン 4.7.0 以降の場合:
2. メタストアを再起動します。
sudo stop hive-hcatalog-server
sudo start hive-hcatalog-server
sudo status hive-hcatalog-server
注: sudo restart hive-hcatalog-server コマンドを使用してメタストアの再起動を試みないでください。
3. hive-server2 を再起動します。
sudo stop hive-server2
sudo start hive-server2
sudo status hive-server2
sudo stop hive-metastore
sudo start hive-metastore
sudo status hive-metastore
3. hive-server2 を再起動します。
sudo stop hive-server2
sudo start hive-server2
sudo status hive-server2