hive 在处理 orc 动态分区插入时 会出现 gc heap over size 之类的问题
问题sql
-- xxx 是个orc 的表
set hive.execution.engine=mr ;
-- 这里用 mr 会出 gc 的问题 ,可行的化用 spark
set hive.exec.dynamic.partition=true ;
set hive.exec.dynamic.partition.mode=nonstrict ;
set hive.exec.max.dynamic.partitions.pernode=1500 ;
set hive.exec.max.dynamic.partitions =1500 ;
insert overwrite table xxx_orc partition (day)
select `(day)+.+` , trandt as day from ods_xxx where day='20210404' ;
数据情况
数据为一个700w 条数据的表 在特定的一个分区里
将分区里的数据按照数据中的一个字段拆分成对应分区的数据
对应分区 1300 个分区,超过默认1000个分区的限制,所以需要 对于修改动态分区的参数
解决方案
这里的问题时 gc 看起来是
运行过程中 只有 1 个map
使用 spark
引擎使用 spark 无上述问题
map阶段上述sql map阶段被拆分成 8个map
使用text临时表转写
这个 就是来到就操作生成的方法
侧面说明mr下处理orc数据时的优化不是这么好
-- 创建同结构 xxx_text
insert overwrite table xxx_text partition (day)
select `(day)+.+` , trandt as day from ods_xxx where day='20210404' ;
insert overwrite table xxx_orc partition (day)
select * from xxx_text ;
mr 调参
解决方案
-- 3. 增大map 的堆内存空间。
-- 实测 这个 改为 16192m 有效
-- mapreduce.map.memory.mb和 mapreduce.map.java.opts
set mapreduce.map.java.opts ;
在后面加 -Xmx 16192m
道听途说的其他方案,有待研究
参数调整
-- 如果出现oom,说明使用的是hive默认实现方式并且用了orc或parquet作为target 表的格式。
-- 1. 开始强制开启reduce,可以解决
--- 没有reduce 阶段没什么用
SET hive.optimize.sort.dynamic.partition=true;
-- 2. 减小maxSplit,相当于把map数变多,让分区基数分散到多个map上,减少单个map的内存压力,不过这个跟数据分布也有关。
set mapred.max.split.size 设置一个小于128m的数
使用distribute by 打散对应的数据
https://stackoverflow.com/questions/58458406/maximum-dynamic-partitions-in-hive-limit