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

问题描述

由于堆空间问题无法处理太多分区,我的脚本失败。为了避免这个问题,我试图将所有分区插入一个分区,但我面临以下错误

失败:SemanticException [错误 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. ?

解决方法

您正在插入静态分区(目标表分区子句中指定的分区值),在这种情况下,您不应在选择中包含分区列。而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 之外,您还可以设置每个减速器的最大字节数。此设置将限制单个减速器处理的数据量,也可能有助于 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 的确切发生位置并进行相应修复。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...