首页 > 解决方案 > hive 脚本由于堆空间问题而失败,无法处理太多分区

问题描述

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

失败:语义异常 [错误 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. ?

标签: hivehiveqlhadoop2hadoop-partitioning

解决方案


您正在插入静态分区(在目标表分区子句中指定的分区值),在这种情况下,您不应该在选择中有分区列。而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 发生的确切位置并相应地进行修复。


推荐阅读