Sqoop import GC overhead limit exceeded 或者 Halting due to Out Of Memory Error解决思路

背景:

最近笔者在公司为公司搭建大数据集群已经小有成果,基本服务已经打通,也做了不少线上任务,但是在任务开发的过程中发现使用sqoop导数据经常会遇到资源不足导致报错,由于sqoop是java开发,虽然以前对这种问题屡见不鲜,但是在大数据集群中这些资源问题就显得特别多OOM,java head space栈溢出、甚至有时候还会出现GC overhead limit exceeded GC的问题。笔者特此总结希望对大家有所帮助。

报错:

在这里插入图片描述在这里插入图片描述

分析

遇到这些问题首先不要慌张,这可能并不是你自己的原因,可能就是资源配置不足引起,这个时候应该灵活应对,因为我们知道向公司伸手要钱实在太难。其实这个问题也要分为几个阶段去看:

出现 – java heap问题

我们应该考虑mysql是否使用了诸如mysql mycat代理,是否是将代理查挂了针对这种情况我们考虑减少每批次抓取数据的条尝试解决。

 #配置每次抓取的条数,这个时候应该调小
 #sqoop参数
 --fetch-size 10000
 # mysql JDBC中添加
 --connect jdbc:mysql://localhost:3306/your_database&defaultFetchSize=10000&useCursorFetch=true 

如果是代理挂了应该及时联系运维重启,然后在设置参数与运维一起进行商讨测试。

Out Of Memory 问题或者GC limit xxxxx问题

在使用sqoop导数据时我们应当知道sqoop只启动maptask,这里以mysql数据导入到hive数据为例,如果不注意设置MapReduce的资源,是会出现一个叫做GC limit xxxxx的错误的。使用一下脚本为例:

sqoop import \
--connect jdbc:mysql://localhost:3306/your_database \
--username root \
--password 123456 \
--target-dir /user/hive/warehouse/xxxx/xxx \
--hive-import \
--hive-database hive_database \
--hive-table hive_tableName\
--as-parquetfile \
--null-string '\\N' \
--null-non-string '\0' \
--fields-terminated-by '\001' \
--table mysql_tableName \
--fetch-size 1000

运行这个命令的时候,程序在yarn中申请到了集群配置的内存资源,然后,任务失败了,报出一个GC limit的错误,当出现这样的错误的时候,很显然就是sqoop在进行数据传输的过程当中,因为内存不足,引发了错误。那么,如何让sqoop在创建一个mapreduce的任务时候,使用比较大的硬件资源呢。通过官网的文档得知,sqoop中有一个参数可以调整hadoop的参数,利用sqoop的-D <key=value>的参数可以让sqoop的job启动的时候申请更多的资源,这就提醒我们通用的sqoop脚本并不是在所有的场景下都适用。所以对不同任务因地制宜分配不同资源尤为重要。
因此可以尝试的解决思路有两个:

  • 增加每个maptask资源
-D yarn.scheduler.minimum-allocation-mb=8096 \
-D yarn.scheduler.maximum-allocation-mb=16192 \
-D mapreduce.map.memory.mb=8096 \
-D mapreduce.reduce.memory.mb=8096 \
--connect jdbc:mysql://localhost:3306/your_database \
--username root \
--password 123456 \
--target-dir /user/hive/warehouse/xxxx/xxx \
--hive-import \
--hive-database hive_database \
--hive-table hive_tableName\
--as-parquetfile \
--null-string '\\N' \
--null-non-string '\0' \
--fields-terminated-by '\001' \
--table mysql_tableName \
--fetch-size 1000

使用上述的脚本之后,程序占用的内存明显提升,如果所需资源和当前资源差别不大这时候就可以解决掉问题。
简单介绍下这几个参数:

  • yarn.scheduler.minimum-allocation-mb
    每个container想RM申请内存的最小大小。兆字节。内存请求小于此值,实际申请到的是此值大小。默认值偏大
  • yarn.scheduler.maximum-allocation-mb
    每个container向RM申请内存的最大大小,兆字节。申请值大于此值,将最多得到此值内存。注意设置的值一定要小于集群自身配置的最大值,否则报错,这很容易理解我箱子就这么大,你给我箱子划分空间最大也就是箱子这么大
  • mapreduce.map.memory.mb
    一个 Map Task 可使用的内存上限(单位:MB),默认为 1024。如果 Map Task 实际使用的资源量超过该值,则会被强制杀死。
  • mapreduce.reduce.memory.mb
    一个 Reduce Task 可使用的资源上限(单位:MB),默认为 1024。如果 Reduce Task 实际使用的资源量超过该值,则会被强制杀死。
  • 增加maptask数量
    这种情况主要针对当前所配置的资源和所需资源差别比较大。可以考虑多channel方式,需要配置如下参数:
--split-by `field`
-m 10

如果以上方案一起使用都不起作用,建议更换导数据工具,不要死乞白赖的吊死在sqoop上,因为不至于为了导数据去增加集群资源配置。

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

扫地增

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值