spark任务java.lang.IllegalArgumentException: Size exceeds Integer.MAX_VALUE

crash:“Caused by: java.lang.RuntimeException: java.lang.IllegalArgumentException: Size exceeds Integer.MAX_VALUE”

这是 spark 的一个经典错误,很有可能就是 shuffle 的时候有太大的 key 或 value 造成的(当然,此 crash 也有可能涉及 序列化、反序列化、cache 等环节原因)。spark默认的each partition size is <= 2GB。

原来我分了300份报错,
var data = hc.sql(s"select pri_acct_no_conv, trans_id, trans_at, pdate, loc_trans_tm, acpt_ins_id_cd, trans_md, cross_dist_in,trans_id, " +
s"trim($srcColumn) as s r c C o l u m n , " + s " t r i m ( srcColumn," + s"trim( srcColumn,"+s"trim(destColumn) as $destColumn " +
s"from t a b l e N a m e " + s " w h e r e p d a t e > = tableName " + s"where pdate>= tableName"+s"wherepdate>=beginDate and pdate<=$endDate").repartition(300).persist(StorageLevel.MEMORY_AND_DISK_SER)

在UI 界面,在执行persist(StorageLevel.MEMORY_AND_DISK_SER)的时候,会显示input进程,例如下图:
在这里插入图片描述
Input大约84.5G的时候,才进行了117/5360阶段,因此可以推算出总数据量大约在3800G左右。
这样一来,至少得分配3800/2 =1900个partition才够。
碰到的spark程序的错误(Size exceeds Integer.MAX_VALUE)以及其他一点优化

因此,我后面分配了3000的参数以后,程序就能正常运行了,大概在40分钟左右所有程序就结束了。
var data = hc.sql(s"select pri_acct_no_conv, trans_id, trans_at, pdate, loc_trans_tm, acpt_ins_id_cd, trans_md, cross_dist_in,trans_id, " +
s"trim($srcColumn) as s r c C o l u m n , " + s " t r i m ( srcColumn," + s"trim( srcColumn,"+s"trim(destColumn) as $destColumn " +
s"from t a b l e N a m e " + s " w h e r e p d a t e > = tableName " + s"where pdate>= tableName"+s"wherepdate>=beginDate and pdate<=$endDate").repartition(3000).persist(StorageLevel.MEMORY_AND_DISK_SER)

根据某司机的经验,如果数据量没这么大的话,repartition的参数跟在spark-submit文件中配置的
–num-executors 保持差不多就够了,这样性能最好。

顺便说一句,persist和cache函数在数据量较大的情况下还是挺耗时间的,cache不是很明显,persist很明显,所以不要乱加persist。

哦,该程序中还发现
var dataFrame1=transferData_tmp.select(s" s r c C o l u m n " ) . d i s t i n c t ( ) v a r d a t a F r a m e 2 = t r a n s f e r D a t a t m p . s e l e c t ( s " {srcColumn}").distinct() var dataFrame2=transferData_tmp.select(s" srcColumn").distinct()vardataFrame2=transferDatatmp.select(s"{destColumn}").distinct()
var cardRdd_transfer= dataFrame1.unionAll(dataFrame2).distinct().map {_.getString(0)}

要比下面这样写法要快不少(感觉跟mapreduce中的combine函数的思路比较像吧。)
var dataFrame1=transferData_tmp.select(s" s r c C o l u m n " ) v a r d a t a F r a m e 2 = t r a n s f e r D a t a t m p . s e l e c t ( s " {srcColumn}") var dataFrame2=transferData_tmp.select(s" srcColumn")vardataFrame2=transferDatatmp.select(s"{destColumn}")
var cardRdd_transfer= dataFrame1.unionAll(dataFrame2).distinct().map {_.getString(0)}

在对一些RDD或者dataframe操作的时候,碰到下面这些问题

Container killed by YARN for exceeding memory limits. 5.6 GB of 5.5 GB physical memory used. Consider boosting spark.yarn.executor.memoryOverhead.

可以尝试对这些RDD 进行repartition,然后再操作。我理解的repartition在两方面比较有用,1是当中间计算的结果过于分散,我们使用repartition可以适当地将数据进行集中,然后在进行计算加快计算速度。2是当partition过少,导致每个partition上的数据量过大的时候,repartition进行增大数量可以分散每个partition上的数量。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值