Hive がクエリ結果を出力する際に発生する、Amazon EMR での Hive Java ヒープスペースの例外 (OutOfMemoryError) の解決方法を教えてください。

最終更新日: 2022 年 5 月 23 日

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 クエリを再度実行します。

ログで OutOfMemoryError を特定する

ログの場所に次のエラーがないか確認します (例: /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 を引き上げます。hive-env 分類用の Amazon EMR 再設定 API を使用して HADOOP_HEAPSIZE を引き上げることもできます。デフォルト値は 1000 です。ユースケースに応じて増やします。次に、Hive クエリを再度実行します。

export HADOOP_HEAPSIZE=2048

重要: この設定は、サービスの再起動後に hive-server2、Hive メタストア、および Hive CLI に適用されます。これらの各サービスに対して、別の値を設定することもできます。

クラスター作成時のメモリ割り当ての更新

Amazon EMR は、設定オブジェクトを使用してクラスターを更新するときにデフォルト設定を更新する設定 API オペレーションを提供します。ユースケースに基づいて HADOOP_HEAPSIZE の値を更新します。

{
  "Classification": "hive-env",
  "Properties": {},
  "Configurations": [
    {
      "Classification": "export",
      "Properties": {
        "HADOOP_HEAPSIZE": "2048"
      },
      "Configurations": []
    }
  ]
}

実行中のクラスターのメモリ割り当ての更新

SSH を使用してマスターモードに接続するか、または Amazon EMR 再設定 API により、実行中のクラスターで HADOOP_HEAPSIZE の値を引き上げることができます。Amazon EMR 再設定 API は、Amazon EMR リリース 5.21 以降でのみ使用できます。メモリ更新が SSH によってクラスターに対して行われた場合、変更を有効にするには、hive サービスを再起動する必要があります。

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 ドキュメントの「Garbage collection」および「Java HotSpot VM Options」を参照してください。

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 Runtime Environment (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 を再起動する必要がある場合があります。hive-server 2 を再起動すると、クラスターで実行中のクエリに影響します。クエリが実行されていないときに、または計画されたメンテナンスウィンドウ中に、プロセスを再開することがベストプラクティスです。

hive のプロセスを再起動するために使用するコマンドは、Amazon EMR のリリースバージョンによって異なります。詳細については、「Amazon EMR でサービスを再起動するにはどうすればよいですか?」を参照してください。

Amazon EMR リリースバージョン 5.30 以降、または 6.0 以降の場合:

1.    SSH を使用してマスターノードに接続します。

2.    メタストアを再起動します。

sudo systemctl stop hive-hcatalog-server
sudo systemctl start hive-hcatalog-server
sudo systemctl status hive-hcatalog-server

3.    hive-server 2 を再起動します。

sudo systemctl stop hive-server2
sudo systemctl start hive-server2
sudo systemctl status hive-server2

Amazon EMR リリースバージョン 4.7.0~5.29 の場合:

1.    SSH を使用してマスターノードに接続します。

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

Amazon EMR リリースバージョン 4.0.0~4.6:

1.    SSH を使用してマスターノードに接続します。

2.    メタストアを再起動します。

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

この記事はお役に立ちましたか?


請求に関するサポートまたは技術サポートが必要ですか?