Correggere un errore Hive di memoria insufficiente in Azure HDInsightFix a Hive out of memory error in Azure HDInsight

Informazioni su come risolvere un errore Hive di memoria insufficiente durante l'elaborazione tabelle di grandi dimensioni configurando le impostazioni di memoria Hive.Learn how to fix a Hive out of memory error when process large tables by configuring Hive memory settings.

Eseguire una query Hive su tabelle di grandi dimensioniRun Hive query against large tables

Un cliente ha eseguito una query Hive:A customer ran a Hive query:

SELECT
    COUNT (T1.COLUMN1) as DisplayColumn1,
    …
    …
    ….
FROM
    TABLE1 T1,
    TABLE2 T2,
    TABLE3 T3,
    TABLE5 T4,
    TABLE6 T5,
    TABLE7 T6
where (T1.KEY1 = T2.KEY1….
    …
    …

Dettagli della query:Some nuances of this query:

  • T1 è l'alias di una tabella di grandi dimensioni, TABLE1, che ha molti tipi di colonna STRING.T1 is an alias to a big table, TABLE1, which has lots of STRING column types.
  • Le altre tabelle non hanno tali dimensioni, ma dispongono di un numero elevato di colonne.Other tables are not that big but do have many columns.
  • Tutte le tabelle sono unite tra loro, in alcuni casi con più colonne in TABLE1 e altre.All tables are joining each other, in some cases with multiple columns in TABLE1 and others.

La query Hive ha richiesto 26 minuti in un nodo del cluster HDInsight A3 24.The Hive query took 26 minutes to finish on a 24 node A3 HDInsight cluster. Il cliente ha notato i messaggi di avviso seguenti:The customer noticed the following warning messages:

Warning: Map Join MAPJOIN[428][bigTable=?] in task 'Stage-21:MAPRED' is a cross product
Warning: Shuffle Join JOIN[8][tables = [t1933775, t1932766]] in Stage 'Stage-4:MAPRED' is a cross product

Tramite il motore di esecuzione di Tez.By using the Tez execution engine. La stessa query ha richiesto 15 minuti e quindi ha generato l'errore seguente:The same query ran for 15 minutes, and then threw the following error:

Status: Failed
Vertex failed, vertexName=Map 5, vertexId=vertex_1443634917922_0008_1_05, diagnostics=[Task failed, taskId=task_1443634917922_0008_1_05_000006, diagnostics=[TaskAttempt 0 failed, info=[Error: Failure while running task:java.lang.RuntimeException: java.lang.OutOfMemoryError: Java heap space
    at
org.apache.hadoop.hive.ql.exec.tez.TezProcessor.initializeAndRunProcessor(TezProcessor.java:172)
    at org.apache.hadoop.hive.ql.exec.tez.TezProcessor.run(TezProcessor.java:138)
    at
org.apache.tez.runtime.LogicalIOProcessorRuntimeTask.run(LogicalIOProcessorRuntimeTask.java:324)
    at
org.apache.tez.runtime.task.TezTaskRunner$TaskRunnerCallable$1.run(TezTaskRunner.java:176)
    at
org.apache.tez.runtime.task.TezTaskRunner$TaskRunnerCallable$1.run(TezTaskRunner.java:168)
    at java.security.AccessController.doPrivileged(Native Method)
    at javax.security.auth.Subject.doAs(Subject.java:415)
    at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1628)
    at
org.apache.tez.runtime.task.TezTaskRunner$TaskRunnerCallable.call(TezTaskRunner.java:168)
    at
org.apache.tez.runtime.task.TezTaskRunner$TaskRunnerCallable.call(TezTaskRunner.java:163)
    at java.util.concurrent.FutureTask.run(FutureTask.java:262)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.OutOfMemoryError: Java heap space

L'errore persiste quando si usa una macchina virtuale più grande (ad esempio, D12).The error remains when using a bigger virtual machine (for example, D12).

Debug dell'errore di memoria insufficienteDebug the out of memory error

Il supporto Microsoft insieme al team di progettazione ha rilevato che uno dei problemi che provocava l'errore di memoria insufficiente era un problema noto descritto in Apache JIRA:Our support and engineering teams together found one of the issues causing the out of memory error was a known issue described in the Apache JIRA:

When hive.auto.convert.join.noconditionaltask = true we check noconditionaltask.size and if the sum  of tables sizes in the map join is less than noconditionaltask.size the plan would generate a Map join, the issue with this is that the calculation doesnt take into account the overhead introduced by different HashTable implementation as results if the sum of input sizes is smaller than the noconditionaltask size by a small margin queries will hit OOM.

hive.auto.convert.join.noconditionaltask nel file hive-site.xml file è stato impostato su true:The hive.auto.convert.join.noconditionaltask in the hive-site.xml file was set to true:

<property>
    <name>hive.auto.convert.join.noconditionaltask</name>
    <value>true</value>
    <description>
          Whether Hive enables the optimization about converting common join into mapjoin based on the input file size.
          If this parameter is on, and the sum of size for n-1 of the tables/partitions for a n-way join is smaller than the
          specified size, the join is directly converted to a mapjoin (there is no conditional task).
    </description>
  </property>

È probabile che map join sia la causa dell'errore di memoria insufficiente nello spazio dell'heap di Java.It is likely map join was the cause of the Java Heap Space our of memory error. Come illustrato nel post di blog sulle impostazioni della memoria Yarn di Hadoop in HDInsight, quando si usa il motore di esecuzione Tez lo spazio dell'heap effettivamente usato appartiene al contenitore Tez.As explained in the blog post Hadoop Yarn memory settings in HDInsight, when Tez execution engine is used the heap space used actually belongs to the Tez container. Vedere l'immagine seguente che descrive la memoria del contenitore Tez.See the following image describing the Tez container memory.

Diagramma della memoria del contenitore Tez: errore Hive di memoria insufficiente

Come suggerisce il post di blog, le due impostazioni di memoria seguenti definiscono la memoria del contenitore per l'heap: hive.tez.container.size e hive.tez.java.opts.As the blog post suggests, the following two memory settings define the container memory for the heap: hive.tez.container.size and hive.tez.java.opts. In base all'esperienza attuale, l'eccezione di memoria insufficiente non è correlata alle dimensioni ridotte del contenitore.From our experience, the out of memory exception does not mean the container size is too small. Ossia, ad essere ridotte solo le dimensioni dell'heap di Java (hive.tez.java.opts).It means the Java heap size (hive.tez.java.opts) is too small. Pertanto ogni volta che viene visualizzato un errore di memoria insufficiente, è possibile provare ad aumentare hive.tez.java.opts.So whenever you see out of memory, you can try to increase hive.tez.java.opts. Se necessario, può essere necessario aumentare hive.tez.container.size.If needed you might have to increase hive.tez.container.size. L'impostazione java.opts deve essere circa l'80% di container.size.The java.opts setting should be around 80% of container.size.

Nota

L'impostazione hive.tez.java.opts deve sempre essere inferiore a hive.tez.container.size.The setting hive.tez.java.opts must always be smaller than hive.tez.container.size.

Poiché una macchina D12 ha una memoria di 28 GB, si è deciso di usare una dimensione del contenitore di 10 GB (10.240 MB) e assegnare l'80% a java.opts:Because a D12 machine has 28GB memory, we decided to use a container size of 10GB (10240MB) and assign 80% to java.opts:

SET hive.tez.container.size=10240
SET hive.tez.java.opts=-Xmx8192m

Con le nuove impostazioni, la query è stata eseguita in meno di dieci minuti.With the new settings, the query successfully ran in under 10 minutes.

Passaggi successiviNext steps

Un errore di memoria insufficiente non indica necessariamente che le dimensioni del contenitore sono troppo piccole.Getting an OOM error doesn't necessarily mean the container size is too small. Al contrario, è necessario configurare le impostazioni della memoria in modo che le dimensioni dell'heap aumentino e raggiungano almeno l'80% delle dimensioni della memoria del contenitore.Instead, you should configure the memory settings so that the heap size is increased and is at least 80% of the container memory size. Per l'ottimizzazione delle query Hive, vedere Ottimizzare le query Hive per Hadoop in HDInsight.For optimizing Hive queries, see Optimize Hive queries for Hadoop in HDInsight.