记一次hive写入orc文件失败

报错信息为map端的orc写入堆内存溢出相关错误,错误如下:

java.lang.OutOfMemoryError: Java heap space                  
java.lang.OutOfMemoryError: GC overhead limit exceeded

现设置如下参数解决:

set hive.exec.orc.default.compress.size=8192;
set mapreduce.map.memory.mb=2048;
set hive.exec.orc.default.buffer.size=16384;
set hive.exec.orc.skip.corrupt.data=true;

原因分析:
orc文件结构图

    在ORC格式的hive表中,记录首先会被横向的切分为多个stripes,然后在每一个stripe内数据以列为单位进行存储。使用ORC文件格式时,用户可以使用HDFS的每一个block存储ORC文件的一个stripe。对于一个ORC文件来说,stripe的大小一般需要设置得比HDFS的block小,如果不这样的话,一个stripe就会分别在HDFS的多个block上,当读取这种数据时就会发生远程读数据的行为。如果设置stripe的只保存在一个block上的话,如果当前block上的剩余空间不足以存储下一个strpie,ORC的writer接下来会将数据打散保存在block剩余的空间上,直到这个block存满为止。这样,下一个stripe又会从下一个block开始存储。

    当ORC writer写数据时,会将整个stripe保存在内存中。由于stripe的默认值一般比较大, 大尺寸的stripes使得从HDFS读数据更高效,但当有多个ORC writer同时写数据时,可能会导致内存不足。为了现在这种并发写时的内存消耗,ORC文件中引入了一个内存管理器。在一个Map或者Reduce任务中内存管理器会设置一个阈值,这个阈值会限制writer使用的总内存大小。当有新的writer需要写出数据时,会向内存管理器注册其大小(一般也就是stripe的大小),当内存管理器接收到的总注册大小超过阈值时,内存管理器会将stripe的实际大小按该writer注册的内存大小与总注册内存大小的比例进行缩小。当有writer关闭时,内存管理器会将其注册的内存从总注册内存中注销。

    因此,考虑为orc写数据,会将stripe保持到内存中,而stripe的值大,导致内存溢出。每个stripe的默认大小为256MB。我们调小至64M,set hive.exec.orc.default.stripe.size=67108864;不报错了。

阿里P7数据技术专家,修改简历、模拟面试+vx:wodatoucai

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值