Como resolvo as exceções de espaço “OutOfMemoryError” de heap do Java no Hive no Amazon EMR que ocorrem quando o Hive emite os resultados da consulta?

8 minuto de leitura
0

Estou executando uma consulta do Apache Hive no Amazon EMR. O Hive lança uma exceção OutOfMemoryError ao gerar os resultados da consulta.

Descrição breve

A exceção OutOfMemoryError geralmente ocorre durante os comandos INSERT OVERWRITE quando não há espaço de pilha suficiente em hive-server2, no metastore do Hive ou no lado do cliente. Para resolver esse problema, aumente a alocação máxima de memória para a JVM ou aumente o HADOOP_HEAPSIZE.

Resolução

Use uma ou mais das seguintes soluções para resolver exceções de OutOfMemoryError.

Observação: essas soluções não abrangem as exceções de OutOfMemoryError que ocorrem durante o ajuste da memória do contêiner Apache Tez.

Aumentar a alocação máxima de memória para a JVM

Quando você inicia um shell do Hive, 1 GB de memória é alocado por padrão. A alocação máxima de memória é definida pelo parâmetro -Xmx. Se seu processo tentar usar mais do que o valor máximo, o Hive encerrará o processo e lançará a exceção OutOfMemoryError. Para resolver esse problema, aumente o valor de -Xmx no script do shell do Hive (em MB) e execute sua consulta do Hive novamente.

Identificar OutOfMemoryError em logs

Verifique o seguinte erro em seu local de log (por exemplo: /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 você ver essa mensagem de erro, o espaço de pilha da JVM está ficando sem memória. Aumente HADOOP_HEAPSIZE para o serviço de CLI do Hive /etc/hive/conf/hive-env.sh, conforme mostrado no exemplo a seguir. Você também pode aumentar HADOOP_HEAPSIZE usando a API de reconfiguração do Amazon EMR para classificação hive-env. O valor padrão é 1000. Aumente-o conforme apropriado para seu caso de uso. Em seguida, execute a consulta do Hive novamente.

export HADOOP_HEAPSIZE=2048

Importante: essa configuração se aplica ao hive-server2, ao metastore do Hive e à CLI do Hive após a reinicialização desses serviços. Opcionalmente, você pode definir valores separados para cada um desses serviços.

Atualizar a alocação de memória ao criar um cluster

O Amazon EMR fornece a operação da API de configuração para atualizar a configuração padrão quando você atualiza o cluster usando o objeto de configuração. Atualize o valor HADOOP_HEAPSIZE com base no seu caso de uso:

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

Atualizar a alocação de memória em um cluster em execução

Você pode aumentar o valor de HADOOP_HEAPSIZE em um cluster em execução conectando-se ao modo mestre usando SSH ou à API de reconfiguração do Amazon EMR. A API de reconfiguração do Amazon EMR está disponível somente para as versões 5.21 e posteriores do Amazon EMR. Se as atualizações de memória forem feitas pelo SSH no cluster, você deverá reiniciar os serviços do hive para que as alterações entrem em vigor.

Beeline ou SQL Workbench/J

1.    Se você estiver executando a mesma consulta do Beeline ou do SQL Workbench/J, verifique /mnt/var/log/hive/hive-server2.log and hive-server2.out para ver se há erros de coleta de resíduos no espaço do heap. Por exemplo:

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.    Se você encontrar erros semelhantes a esse, aumente HADOOP_HEAPSIZE para hive-server2 em /etc/hive/conf/hive-env.sh. Essa configuração também é aplicável ao metastore do Hive e ao cliente do Hive.

export HADOOP_HEAPSIZE=2048

Opcionalmente, use instruções condicionais para especificar tamanhos de pilha diferentes para o hive-server2, o metastore e o cliente. Por exemplo:

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.    Execute a consulta do Hive novamente depois de atualizar essas configurações. Se você ainda receber a exceção OutOfMemoryError e estiver executando vários clientes ao mesmo tempo, continue na etapa 4. Se você ainda receber a exceção OutOfMemoryError e não estiver executando vários clientes ao mesmo tempo, vá para a etapa 8.

4.    Aumente os parâmetros -Xmx para cada cliente, conforme apropriado para seu caso de uso.

5.    Escolha o coletor de lixo apropriado para seu caso de uso adicionando -XX:+UseParNewGC (novo coletor de lixo paralelo) ou -XX:+UseConcMarkSweepGC (coletor de lixo de varredura simultânea de marcas) nas linhas HADOOP_OPTS, conforme mostrado no exemplo a seguir. Para mais informações sobre como escolher um coletor de resíduos, consulte Coleta de resíduos e Opções Java HotSpot VM na documentação do 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.    O Hive lança a exceção OutOfMemoryError se a coleta de resíduos não for bem-sucedida em um período de tempo especificado. Para remover o limite de tempo, remova -XX:-UseGCOverheadLimit ou substitua-o por -XX:+UseGCOverheadLimit. Opcionalmente, modifique -XX:-UseGCOverheadLimit para especificar um novo limite de tempo para a coleta de resíduos. Para mais informações, consulte The Parallel Collector na documentação do Java.

7.    Execute a consulta do Hive novamente. Se o Hive gerar um erro de espaço na pilha no terminal durante o tempo de execução (e se não houver erros no hive.log ou no hive-server2.log), então seu cliente Hive provavelmente está ficando sem memória. Por exemplo:

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 resolver esse erro, aumente a memória do cliente e execute a consulta novamente..

9.    Se o Hive ainda gerar a exceção OutOfMemoryError, conclua as etapas a seguir para seu cliente.

Beeline:

Por padrão, o Beeline tenta armazenar em buffer toda a relação de saída antes de imprimi-la em stdout. Esse comportamento pode causar uma exceção OutOfMemoryError quando a relação de saída é grande. Para resolver a exceção OutOfMemoryError no Beeline, inicie o Beeline usando o comando a seguir e tente novamente a consulta do Hive:

beeline --incremental=true

SQL Workbench/J:

Em um Java Runtime Environment (JRE) de 32 bits, a aplicação pode usar até 1 GB de memória por padrão. Em um JRE de 64 bits, a aplicação pode usar até 65% da memória física disponível por padrão. Para verificar a quantidade de memória disponível para a aplicação, escolha **Ajuda ** e depois Sobre.

  • **Para macOS:**aumente o valor de -Xmx1024m no arquivo Info.plist conforme necessário. Info.plist geralmente está localizado no diretório /Applications/SQLWorkbenchJ2.app/Contents. Por exemplo, para dobrar a quantidade de memória disponível para a aplicação, altere o valor de -Xmx1024m para -Xmx2048m. Em seguida, execute a consulta novamente.
  • Para Windows: crie um arquivo INI e adicione o parâmetro vm.heapsize.preferred ao arquivo INI para aumentar a quantidade de memória disponível para a aplicação.

Se estiver usando scripts shell ou em lote, poderá aumentar a memória disponível ao instalar o SQL Workbench/J. O comando no exemplo a seguir cria 3 GB de memória disponível durante a instalação:

java -Xmx3g -jar sqlworkbench.jar

Observação: se a exceção OutOfMemoryError estiver no lado do cliente e não em hive-server2 ou na CLI do Hive, salve a saída no Amazon Simple Storage Service (Amazon S3) ou no HDFS. Não use o Beeline ou o SQL Workbench/J para ver os resultados da consulta.

Reiniciar o Hive

Se você modificar as propriedades do Hive em hive-site.xml ou hive-env.sh, talvez seja necessário reiniciar o Hive antes que as configurações atualizadas entrem em vigor. A reinicialização de hive-server 2 afeta as consultas em execução no cluster. É uma prática recomendada reiniciar os processos quando nenhuma consulta está em execução ou durante uma janela de manutenção planejada.

Os comandos que você usa para reiniciar os processos do hive variam de acordo com a versão de lançamento do Amazon EMR. Para mais informações, consulte Como reiniciar um serviço no Amazon EMR?

Para as versões de lançamento do Amazon EMR 5.30 e posteriores ou 6.0 e posteriores:

1.    Conecte-se ao nó principal usando SSH.

2.    Reinicie o 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 as versões de lançamento do Amazon EMR 4.7.0 a 5.29:

1.    Conecte-se ao nó principal usando SSH.

2.    Reinicie o metastore:

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

Observação: não tente reiniciar o metastore usando o comando sudo restart hive-hcatalog-server.

3.    Reinicie hive-server2:

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

Para as versões de lançamento do Amazon EMR 4.0.0 a 4.6:

1.    Conecte-se ao nó principal usando SSH.

2.    Reinicie o 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

Informações relacionadas

Como posso usar registros para solucionar problemas com consultas do Hive no Amazon EMR?

Ajuste de escala de recursos do cluster

Configuração da tarefa

AWS OFICIAL
AWS OFICIALAtualizada há 2 anos