首先有两个大背景须要说明以下:
说明1:split_size,设定一个map的最大数据输入量,单位M,默认256M。用户能够经过控制这个变量,从而达到对map端输入的控制。设置语句:set odps.sql.mapper.split.size=256。通常在调整这个设置时,每每是发现一个map instance处理的数据行数太多。sql
说明2:小文件越多,须要instance资源也越多,MaxCompute对单个Instance能够处理的小文件数限制为120个,如此形成浪费资源,影响总体的执行性能(文件的大小小于块Block 64M的文件)。app
原始Logview Detail:性能
能够发现Job只调起一个Map Instance,供处理了156M的数据,但这些数据共有5千多万的记录(单记录平均3个byte),花费了25分钟。
此外,从TimeLine看能够发现,整个Job耗费43分钟,map占用了超过60%的时间。故可对map进行优化。大数据
优化手段:调小split_size为16M优化
优化以后的logview:spa
优化后,能够发现,Job调起了7个Map Instance,耗时4分钟;某一个Map处理了27M的数据,6百万记录。(这里能够看出set split_size只是向Job提出申请,单不会严格生效,Job仍是会根据现有的资源状况等来调度Instance)由于Map的变多,Join和Reduce的instance也有增长。整个Job的执行时间也降低到7分钟。3d
原始logview:blog
能够发现,Job调起了4个Map,花费了3个小时没有跑完;查看详细Log,某一个Map由于笛卡尔的缘故,生成的数据量暴涨。
综合考虑,由于该语句使用Mapjoin生成笛卡尔积,再筛选符合条件的记录,两件事情都由map一次性完成,故对map进行优化。资源
策略调低split_size
优化后的logview:get
优化后,能够看到,Job调度了38个map,单一map的生成数据量降低了,总体map阶段耗时也降低到37分钟。
回头追朔这个问题的根源,主要是由于使用mapjoin笛卡尔积的方式来实现udf条件关联的join,致使数据量暴涨。故使用这种方式来优化,看起来并不能从根本解决问题,故咱们须要考虑更好的方式来实现相似逻辑。
本文做者:祎休
本文为云栖社区原创内容,未经容许不得转载。