Come posso risolvere le eccezioni "OutOfMemoryError" dello spazio dell’heap Java di Hive su Amazon EMR che si verificano quando Hive genera i risultati della query?

8 minuti di lettura
0

Sto eseguendo una query Apache Hive su Amazon EMR. Hive genera un'eccezione OutOfMemoryError durante l'emissione dei risultati della query.

Breve descrizione

L'eccezione OutOfMemoryError di solito si verifica durante i comandi INSERT OVERWRITE quando non c'è abbastanza spazio nell'heap su hive-server2, sul metastore Hive o sul lato client. Per risolvere questo problema, aumenta l'allocazione massima di memoria per la JVM o aumenta HADOOP\ _HEAPSIZE.

Risoluzione

Utilizza una o più delle seguenti soluzioni per risolvere le eccezioni OutOfMemoryError.

Nota: Queste soluzioni non coprono le eccezioni OutOfMemoryError che si verificano durante l'ottimizzazione della memoria del container Apache Tez.

Aumenta l'allocazione massima di memoria per la JVM

Quando avvii una shell (interprete di comandi) Hive, per impostazione predefinita viene allocato 1 GB di memoria. L'allocazione massima di memoria è definita dal parametro -Xmx. Se il processo tenta di utilizzare più del valore massimo, Hive interrompe il processo e genera l'eccezione OutOfMemoryError. Per risolvere questo problema, aumenta il valore -Xmx nello script della shell Hive (in MB), quindi esegui nuovamente la query Hive.

Identifica l'errore OutOfMemoryError nei log

Verifica la presenza del seguente errore nella posizione del log (ad esempio: /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

Se visualizzi questo messaggio di errore, lo spazio dell’heap JVM sta esaurendo la memoria. Aumenta HADOOP\ _HEAPSIZE per il servizio Hive CLI in /etc/hive/conf/hive-env.sh, come illustrato nell'esempio seguente. Puoi anche aumentare HADOOP\ _HEAPSIZE utilizzando l'API di riconfigurazione di Amazon EMR per la classificazione hive-env. Il valore predefinito è 1.000. Aumentalo in base al tuo caso d'uso. Quindi, esegui nuovamente la query Hive.

export HADOOP_HEAPSIZE=2048

Importante: Questa impostazione si applica a hive-server2, al metastore Hive e all’Hive CLI dopo il riavvio di questi servizi. Facoltativamente, puoi impostare valori separati per ciascuno di questi servizi.

Aggiornamento dell'allocazione della memoria durante la creazione di un cluster

Amazon EMR fornisce l'operazione di configurazione API per aggiornare la configurazione predefinita quando aggiorni il cluster utilizzando l’oggetto di configurazione. Aggiorna il valore HADOOP\ _HEAPSIZE in base al tuo caso d'uso:

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

Aggiornamento dell'allocazione della memoria su un cluster in esecuzione

Puoi aumentare il valore di HADOOP\ _HEAPSIZE su un cluster in esecuzione connettendoti alla modalità principale tramite SSH o con l’API di riconfigurazione di Amazon EMR. L'API di riconfigurazione di Amazon EMR è disponibile solo per le versioni 5.21 e successive di Amazon EMR. Se gli aggiornamenti della memoria vengono effettuati da SSH nel cluster, è necessario riavviare i servizi hive affinché le modifiche abbiano effetto.

Beeline o SQL Workbench/J

  1. Se stai eseguendo la stessa query da Beeline o SQL Workbench/J, controlla /mnt/var/log/hive/hive-server2.log e hive-server2.out per gli errori di rimozione di oggetti inutili (garbage collection) nello spazio heap. Ad esempio:
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
  1. Se trovi errori simili a questo, aumenta HADOOP\ _HEAPSIZE per hive-server2 in /etc/hive/conf/hive-env.sh. Questa impostazione si applica anche al metastore Hive e al client Hive.
export HADOOP_HEAPSIZE=2048

Facoltativamente, usa le istruzioni condizionali per specificare diverse dimensioni dell'heap per hive-server2, il metastore e il client. Ad esempio:

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
  1. Esegui nuovamente la query Hive dopo aver aggiornato queste impostazioni. Se ricevi ancora l'eccezione OutOfMemoryError e stai eseguendo più client contemporaneamente, continua con il passaggio 4. Se ricevi ancora l'eccezione OutOfMemoryError e non esegui più client contemporaneamente, vai al passaggio 8.

  2. Aumenta i parametri -Xmx per ogni client, in base al tuo caso d'uso.

  3. Scegli il garbage collector più adatto al tuo caso d'uso aggiungendo -XX: +useparNewGC (nuovo garbage collector parallelo) o -XX: +useConcMarkSweepGC (garbage collector Mark Sweep simultaneo) nelle righe HADOOP\ _OPTS, come mostrato nell'esempio seguente. Per ulteriori informazioni sulla scelta di un garbage collector, vedi Rimozione di oggetti inutili (garbage collection) e Opzioni Java HotSpot VM nella documentazione Java.

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
  1. Hive genera l'eccezione OutOfMemoryError se la rimozione di oggetti inutili (garbage collection) non riesce in un determinato periodo di tempo. Per rimuovere il limite di tempo, elimina -XX:-UseGCOverheadLimit o sostituiscilo con -XX:+UseGCOverheadLimit. Facoltativamente, modifica -XX:-UseGCOverheadLimit per specificare un nuovo limite di tempo per la rimozione di oggetti inutili (garbage collection). Per ulteriori informazioni, vedi la sezione The Parallel Collector nella documentazione Java.

  2. Esegui nuovamente la query Hive. Se Hive genera un errore di spazio heap sul terminale durante il runtime, e se non ci sono errori in hive.log o hive-server2.log, è probabile che la memoria del tuo client Hive stia esaurendo. Ad esempio:

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
  1. Per risolvere questo errore, aumenta la memoria del client, quindi esegui nuovamente la query.

  2. Se Hive genera ancora l'eccezione OutOfMemoryError, completa i seguenti passaggi per il tuo client.

Beeline:

Per impostazione predefinita, Beeline tenta di bufferizzare l'intera relazione di output prima di stamparla su stdout. Questo comportamento può causare un'eccezione OutOfMemoryError quando la relazione di output è grande. Per risolvere l'eccezione OutOfMemoryError in Beeline, avvia Beeline usando il seguente comando, quindi riprova la query Hive:

beeline --incremental=true

SQL Workbench/J:

In un ambiente di runtime Java (JRE) a 32 bit, l'applicazione può utilizzare fino a 1 GB di memoria per impostazione predefinita. In un JRE a 64 bit, l'applicazione può utilizzare fino al 65% della memoria fisica disponibile per impostazione predefinita. Per verificare la quantità di memoria disponibile per l'applicazione, scegli Aiuto, quindi seleziona Informazioni.

  • Per macOS: Se necessario, aumenta il valore -Xmx1024m nel file Info.plist. Info.plist si trova in genere nella directory /Applications/SQLWorkbenchJ2.app/Contents. Ad esempio, per raddoppiare la quantità di memoria disponibile per l'applicazione, modifica il valore da -Xmx1024m a -Xmx2048m. Quindi, esegui nuovamente la query.
  • Per Windows: Crea un file INI e poi aggiungi il parametro vm.heapsize.preferred al file INI per aumentare la quantità di memoria disponibile per l'applicazione.

Se si utilizzano script shell o batch, è possibile aumentare la memoria disponibile quando si installa SQL Workbench/J. Il comando nell'esempio seguente crea 3 GB di memoria disponibile durante l'installazione:

java -Xmx3g -jar sqlworkbench.jar

Nota: Se l'eccezione OutOfMemoryError è sul lato client anziché su hive-server2 o sull’Hive CLI, salva l'output su Amazon Simple Storage Service (Amazon S3) o HDFS. Non utilizzare Beeline o SQL Workbench/J per visualizzare i risultati della query.

Riavvio di Hive

Se modifichi le proprietà di Hive in hive-site.xml o hive-env.sh, potresti dover riavviare Hive prima che le impostazioni aggiornate abbiano effetto. Il riavvio di hive-server 2 influisce sulle query in esecuzione sul cluster. È consigliabile riavviare i processi quando non è in esecuzione alcuna query o durante una finestra di manutenzione pianificata.

I comandi utilizzati per riavviare i processi hive variano a seconda della versione di rilascio di Amazon EMR. Per ulteriori informazioni, vedi Come posso riavviare un servizio in Amazon EMR?

Per le versioni di rilascio 5.30 e successive o 6.0 e successive di Amazon EMR:

  1. Connettiti al nodo principale tramite SSH.

  2. Riavvia il metastore:

sudo systemctl stop hive-hcatalog-server
sudo systemctl start hive-hcatalog-server
sudo systemctl status hive-hcatalog-server
  1. Riavvia hive-server 2:
sudo systemctl stop hive-server2
sudo systemctl start hive-server2
sudo systemctl status hive-server2

Per le versioni di rilascio da 4.7.0 a 5.29 di Amazon EMR:

  1. Connettiti al nodo principale tramite SSH.

  2. Riavvia il metastore:

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

Nota: Non tentare di riavviare il metastore utilizzando il comando sudo restart hive-hcatalog-server.

  1. Riavvia hive-server2:
sudo stop hive-server2
sudo start hive-server2
sudo status hive-server2

Per le versioni di rilascio da 4.0.0 a 4.6 di Amazon EMR:

  1. Connettiti al nodo principale tramite SSH.

  2. Riavvia il metastore:

sudo stop hive-metastore
sudo start hive-metastore
sudo status hive-metastore
  1. Riavvia hive-server2:
sudo stop hive-server2
sudo start hive-server2
sudo status hive-server2

Informazioni correlate

Come posso utilizzare i log per risolvere i problemi relativi alle query Hive in Amazon EMR?

Scalabilità delle risorse del cluster

Configurazione delle attività

AWS UFFICIALE
AWS UFFICIALEAggiornata 2 anni fa