优化 Hive 查询。 java.lang.OutOfMemoryError:超出 Java 堆空间/GC 开销限制

Posted

技术标签:

【中文标题】优化 Hive 查询。 java.lang.OutOfMemoryError:超出 Java 堆空间/GC 开销限制【英文标题】:Optimize Hive Query. java.lang.OutOfMemoryError: Java heap space/GC overhead limit exceeded 【发布时间】:2020-07-08 22:13:01 【问题描述】:

由于一直遇到此 OOM 错误,如何优化此表单的查询?还是想出更好的执行计划?如果我删除了 substring 子句,查询会正常工作,这表明这会占用大量内存。

当作业失败时,直线输出会显示 OOM Java 堆空间。在线阅读建议我增加export HADOOP_HEAPSIZE,但这仍然会导致错误。我尝试的另一件事是增加hive.tez.container.sizehive.tez.java.opts(tez 堆),但仍然有这个错误。在 YARN 日志中,可能会超出 GC 开销限制,这表明内存不足和/或查询计划效率极低,因为它无法回收足够的内存。

我正在使用 Azure HDInsight 交互式查询 4.0。 20 个工作节点、D13v2 8 核和 56GB RAM。

源表

create external table database.sourcetable(
  a,
  b,
  c,
  ...
  (183 total columns)
  ...
)
PARTITIONED BY ( 
  W string, 
  X int, 
  Y string, 
  Z int
)

目标表

create external table database.NEWTABLE(
  a,
  b,
  c,
  ...
  (187 total columns)
  ...
  W,
  X,
  Y,
  Z
)
PARTITIONED BY (
  aAAA,
  bBBB
)

查询

insert overwrite table database.NEWTABLE partition(aAAA, bBBB, cCCC)
select
a,
b,
c,
...
(187 total columns)
...
W,
X,
Y,
Z,
cast(a as string) as aAAA, 
from_unixtime(unix_timestamp(b,'yyMMdd'),'yyyyMMdd') as bBBB,
substring(upper(c),1,2) as cCCC
from database.sourcetable

【问题讨论】:

您好,如果以下答案对您有帮助,您可以接受它作为答案(单击答案旁边的复选标记,将其从灰色切换为已填充。)。这对其他社区成员可能是有益的。谢谢。 【参考方案1】:

如果一切正常,请尝试在查询末尾添加按分区键分发:

  from database.sourcetable 
  distribute by aAAA, bBBB, cCCC

因此每个reducer只会创建一个分区文件,占用内存更少

【讨论】:

我添加了目标表以提供清晰的图片。分区中的目标表和查询是否正确?介意我问一下,为什么我们是按源表分区而不是目标表来分配的? @user7644509 抱歉,错过了。它应该是目标分区。以错误的方式阅读您的问题..你是对的【参考方案2】:

尝试对分区列进行排序:

SET hive.optimize.sort.dynamic.partition=true;

启用后,动态分区列将全局排序。这样我们就可以为 reducer 中的每个分区值只打开一个记录写入器,从而减少 reducer 的内存压力。

https://cwiki.apache.org/confluence/display/Hive/Configuration+Properties

【讨论】:

以上是关于优化 Hive 查询。 java.lang.OutOfMemoryError:超出 Java 堆空间/GC 开销限制的主要内容,如果未能解决你的问题,请参考以下文章

Hive优化

优化 HIVE 查询中的连接:c

hive大表和小表MapJoin关联查询优化

Hive性能优化之表设计优化

Hive 优化详解

学习笔记Hive—— 查询优化