¿Cómo puedo solucionar las excepciones de espacio de montón de Hive en Java «OutOfMemoryError» que se producen en Amazon EMR cuando Hive muestra los resultados de la consulta?

9 minutos de lectura
0

Estoy ejecutando una consulta de Apache Hive en Amazon EMR. Hive lanza una excepción OutOfMemoryError al mostrar los resultados de la consulta.

Breve descripción

La excepción OutOfMemoryError se suele producir con los comandos INSERT OVERWRITE cuando no hay suficiente espacio de montón en hive-server2, en el metastore de Hive o en el lado del cliente. Para solucionar este problema, aumente la asignación de memoria máxima para la JVM o incremente HADOOP_HEAPSIZE.

Solución

Utilice una o varias de las siguientes soluciones para resolver las excepciones OutOfMemoryError.

Nota: Estas soluciones no cubren las excepciones OutOfMemoryError que se producen durante el ajuste de la memoria del contenedor de Apache Tez.

Aumento de la asignación de memoria máxima para la JVM

Cuando lanza un shell de Hive, se asigna 1 GB de memoria de forma predeterminada. La asignación de memoria máxima se define mediante el parámetro -Xmx. Si el proceso intenta superar el valor máximo, Hive lo cancela y lanza la excepción OutOfMemoryError. Para solucionar este problema, aumente el valor -Xmx en el script de shell de Hive (en MB) y, a continuación, vuelva a ejecutar la consulta de Hive.

Identificación de OutOfMemoryError en registros

Compruebe si hay el siguiente error en la ubicación del registro (por ejemplo: /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

Si ve este mensaje de error, el espacio del montón de JVM se está quedando sin memoria. Aumente HADOOP_HEAPSIZE para el servicio de CLI de Hive en /etc/hive/conf/hive-env.sh, como se muestra en el siguiente ejemplo. También puede aumentar HADOOP_HEAPSIZE mediante la API de reconfiguración de Amazon EMR para la clasificación de hive-env. El valor predeterminado es 1000. Auméntelo según corresponda para su caso de uso. A continuación, vuelva a ejecutar la consulta de Hive.

export HADOOP_HEAPSIZE=2048

Importante: Esta configuración se aplica a hive-server2, el metastore de Hive y CLI de Hive después de reiniciar estos servicios. Si lo desea, puede establecer valores independientes para cada uno de estos servicios.

Actualización de la asignación de memoria al crear un clúster

Amazon EMR proporciona la operación de la API de configuración para actualizar la configuración predeterminada al actualizar el clúster mediante el objeto de configuración. Actualice el valor de HADOOP_HEAPSIZE en función de su caso de uso:

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

Actualización de la asignación de memoria en un clúster en ejecución

Para aumentar el valor de HADOOP_HEAPSIZE en un clúster en ejecución puede conectarse al modo maestro mediante SSH o utilizar la API de reconfiguración de Amazon EMR. La API de reconfiguración de Amazon EMR solo está disponible para las versiones 5.21 y posteriores de Amazon EMR. Si las actualizaciones de memoria las realiza SSH en el clúster, debe reiniciar los servicios de Hive para que los cambios surtan efecto.

Beeline o SQL Workbench/J

1.    Si ejecuta la misma consulta desde Beeline o SQL Workbench/J, compruebe si hay errores de recopilación de elementos no utilizados en el espacio del montón en /mnt/var/log/hive/hive-server2.log y hive-server2.out. Por ejemplo:

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.    Si encuentra errores similares a este, aumente HADOOP_HEAPSIZE para hive-server2 en /etc/hive/conf/hive-env.sh. Esta configuración también se aplica al metastore y al cliente de Hive.

export HADOOP_HEAPSIZE=2048

Si lo desea, utilice sentencias condicionales para especificar diferentes tamaños de montón para hive-server2, el metastore y el cliente. Por ejemplo:

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.    Vuelva a ejecutar la consulta de Hive después de actualizar esta configuración. Si sigue apareciendo la excepción OutOfMemoryError y ejecuta varios clientes al mismo tiempo, continúe con el paso 4. Si sigue apareciendo la excepción OutOfMemoryError y no está ejecutando varios clientes al mismo tiempo, vaya al paso 8.

4.    Aumente los parámetros -Xmx para cada cliente según convenga en su caso de uso.

5.    Elija el recopilador de elementos no utilizados adecuado para su caso de uso; para ello, añada -XX:+UseParNewGC (nuevo recopilador paralelo de elementos no utilizados) o -XX:+UseConcMarkSweepGC (recopilador de elementos no utilizados con barrido de marcas simultáneo) en las líneas HADOOP_OPTS, como se muestra en el siguiente ejemplo. Para obtener más información sobre cómo elegir un recopilador de elementos no utilizados, consulte Recopilación de elementos no utilizados y Opciones de MV de punto de acceso de Java en la documentación de 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

6.    Hive lanza la excepción OutOfMemoryError si la recopilación de basura no se realiza correctamente en un período de tiempo especificado. Para eliminar el límite de tiempo, quite -XX:-UseGCOverheadLimit o sustitúyalo por -XX:+UseGCOverheadLimit. También puede modificar -XX:-UseGCOverheadLimit para especificar un nuevo límite de tiempo para la recopilación de elementos no utilizados. Para obtener más información, consulte El recopilador paralelo en la documentación de Java.

7.    Vuelva a ejecutar la consulta de Hive. Si Hive muestra un error de espacio de montón en la terminal durante el tiempo de ejecución, y si no hay errores en hive.log ni hive-server2.log, es probable que su cliente de Hive se esté quedando sin memoria. Por ejemplo:

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.    Para solucionar este error, aumente la memoria del cliente y vuelva a ejecutar la consulta.

9.    Si Hive sigue mostrando la excepción OutOfMemoryError, complete los siguientes pasos en su cliente.

Beeline:

De forma predeterminada, Beeline intenta almacenar toda la relación de resultados en el búfer antes de imprimirla en stdout. Este comportamiento puede provocar una excepción OutOfMemoryError cuando la relación de resultados es extensa. Para solucionar la excepción OutOfMemoryError en Beeline, lance Beeline con el siguiente comando y, a continuación, repita la consulta de Hive:

beeline --incremental=true

SQL Workbench/J:

En Java Runtime Environment (JRE) de 32 bits, la aplicación puede utilizar hasta 1 GB de memoria de forma predeterminada. En JRE de 64 bits, la aplicación puede utilizar hasta el 65 % de la memoria física disponible de forma predeterminada. Para comprobar la cantidad de memoria disponible para la aplicación, seleccione Ayuda y, a continuación, Acerca de.

  • En macOS: Aumente el valor -Xmx1024m en el archivo Info.plist según sea necesario. Normalmente, Info.plist se encuentra en el directorio /Applications/SQLWorkbenchJ2.app/Contents. Por ejemplo, para duplicar la cantidad de memoria disponible para la aplicación, cambie el valor -Xmx1024m por -Xmx2048m. A continuación, vuelva a ejecutar la consulta.
  • En Windows:Cree un archivo INI y, a continuación, añada el parámetro vm.heapsize.preferred al archivo INI para aumentar la cantidad de memoria disponible para la aplicación.

Si utiliza scripts de shell o por lotes, puede aumentar la memoria disponible al instalar SQL Workbench/J. El comando del siguiente ejemplo crea 3 GB de memoria disponible durante la instalación:

java -Xmx3g -jar sqlworkbench.jar

Nota: Si la excepción OutOfMemoryError se produce en el lado del cliente y no en hive-server2 ni en la CLI de Hive, guarde el resultado en Amazon Simple Storage Service (Amazon S3) o HDFS. No utilice Beeline ni SQL Workbench/J para ver los resultados de la consulta.

Reinicio de Hive

Si modifica las propiedades de Hive en hive-site.xml o hive-env.sh, es posible que tenga que reiniciar Hive antes de que la configuración actualizada surta efecto. El reinicio de hive-server 2 afecta a las consultas en ejecución en el clúster. Se recomienda reiniciar los procesos cuando no haya consultas en ejecución o durante un período de mantenimiento planificado.

Los comandos que se utilizan para reiniciar los procesos de Hive varían en función de la versión de Amazon EMR. Para obtener más información, consulte ¿Cómo puedo reiniciar un servicio en Amazon EMR?

Para las versiones 5.30 y posteriores o 6.0 y posteriores de Amazon EMR:

1.    Conéctese al nodo maestro mediante SSH.

2.    Reinicie el metastore:

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

3.    Reinicie hive-server 2:

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

Para las versiones 4.7.0 a 5.29 de Amazon EMR:

1.    Conéctese al nodo maestro mediante SSH.

2.    Reinicie el metastore:

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

Nota: No intente reiniciar el metastore con el comando sudo restart hive-hcatalog-server.

3.    Reinicie hive-server2:

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

Para las versiones 4.0.0 a 4.6 de Amazon EMR:

1.    Conéctese al nodo maestro mediante SSH.

2.    Reinicie el metastore:

sudo stop hive-metastore
sudo start hive-metastore
sudo status hive-metastore

3.    Reinicie hive-server2:

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

Información relacionada

¿Cómo puedo utilizar los registros para solucionar problemas con las consultas de Hive en Amazon EMR?

Escalado de recursos del clúster

Configuración de tareas

OFICIAL DE AWS
OFICIAL DE AWSActualizada hace 2 años