hive 脚本由于堆空间问题而失败,无法处理太多分区

Posted

技术标签:

【中文标题】hive 脚本由于堆空间问题而失败,无法处理太多分区【英文标题】:hive script failing due to heap space issue to process too many partitions 【发布时间】:2021-01-19 11:35:43 【问题描述】:

我的脚本由于处理太多分区的堆空间问题而失败。为避免此问题,我尝试将所有分区插入单个分区,但遇到以下错误

失败:语义异常 [错误 10044]:第 1:23 行无法插入目标表,因为列号/类型不同“2021-01-16”:表 insclause-0 有 78 列,但查询有 79 列.

    set hive.exec.dynamic.partition=true;
    set mapreduce.reduce.memory.mb=6144;
    set mapreduce.reduce.java.opts=-Xmx5g;
    set hive.exec.dynamic.partition=true;
    insert overwrite table db_temp.travel_history_denorm partition (start_date='2021-01-16')
    select * from db_temp.travel_history_denorm_temp_bq
    distribute by start_date;```


Can someone please suggest what is the issue, I checked the schema for the tables it is the same. ?

【问题讨论】:

【参考方案1】:

您正在插入静态分区(在目标表分区子句中指定的分区值),在这种情况下,您不应该在选择中有分区列。而select *返回分区列(最后一个),这就是查询失败的原因,应该是没有分区列:

静态分区插入:

insert overwrite table db_temp.travel_history_denorm partition (start_date='2021-01-16')
   select col1, col2, col3 ... --All columns except start_date partition column
     from ...

动态分区:

 insert overwrite table db_temp.travel_history_denorm partition (start_date)
       select * --All columns in the same order, including partition
         from ...

添加distribute by 会触发额外的reduce 步骤,所有记录都根据distribute by 分组,每个reducer 接收单个分区。当您在每个 reducer 中加载许多动态分区时,这有助于解决 OOM 问题。如果不通过每个 reducer 分发,则会在每个分区中创建文件,同时保留太多缓冲区。

除了distribute by,您还可以设置每个reducer 的最大字节数。此设置将限制单个 reducer 处理的数据量,也可能有助于 OOM:

 set hive.exec.reducers.bytes.per.reducer=16777216; --adjust for optimal performance

如果这个数字太小,会触发太多的reducer,如果太大——那么每个reducer都会处理太多的数据。相应调整。

也可以试试这个设置动态分区加载:

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

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

您可以组合所有这些方法:按分区键分发,bytes.per.reducer 和 sort.dynamic.partition 用于动态分区加载。

异常消息还可以帮助了解 OOM 发生的确切位置并相应地进行修复。

【讨论】:

我不想在partition=2021-01-16中插入一天的所有数据,这就是在同一列上提到where子句的原因 @Never_Give_Up 您的查询中没有 WHERE 子句,只有静态分区规范。 WHERE 子句应该在分发之前。无论如何语法不正确。对于静态分区加载,您应该在选择中没有分区列。根据我的建议尝试动态加载 以下是错误,我正在使用 tez 引擎错误:执行任务时遇到错误:尝试_16034529831_0011_0:java.lang.OutOfMemoryError: Java 堆空间 @Never_Give_Up 在哪个容器中?你确定它在减速器中吗?如果是,请尝试该设置。令人惊讶的是 Tez!您在问题中没有提到相同的内容。对于 Tez 添加还设置 hive.tez.auto.reducer.parallelism=true;和内存设置不同:set tez.reduce.memory.mb=6144; set hive.tez.container.size=9216; set hive.tez.java.opts=-Xmx6144m; 我会尝试您的建议以通过优化,看看它是否有效。我接受你的回答。

以上是关于hive 脚本由于堆空间问题而失败,无法处理太多分区的主要内容,如果未能解决你的问题,请参考以下文章

HIVE 加入时间太长,但在 Impala 上速度很快

如果由于CMS gc算法中的关键内存碎片而无法分配内存会发生什么

由于失败,无法执行 hive 交换分区:分区已存在

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

转换为 Dalvik 格式失败:无法执行 dex:Java 堆空间

Windows Mysql启动出现1069错误“由于登录失败而无法启动服务”的处理方法