使用阿里云DataWorks进行数据处理的时候,有时候会遇到一个sql或pyodps(本质上还是转化为sql)执行很长的情况,这个时候有必要对代码进行性能优化。
一、打开ODPS运行评估报告
一个sql脚本执行完毕后,在运维中心的周期实例中右击该任务"查看运行日志"。
然后再找到如下链接即可打开日志的检测报告:
点击后显示如下:
可以看到该任务从13:33运行到16:04,运行了2个半小时左右,性能堪忧。
二、分析LogView的信息
我们对LogView的各部分信息分别进行说明。
1、运行DAG图
显示了整个SQL任务切分为MapReduce任务后的DAG图。
【名称含义】
M:map操作
R:reduce操作
J:join操作
【链路】
链路上比较粗的表示数据量比较大,比较细的表示数据量比较小。
2、任务节点详细信息
该部分展示了Map、Reduce、Join节点任务的详细信息。
IO Records:数据的条数
IO Bytes:数据的大小
Latency:节点运行时长
Failed/Terminated/ALL:节点的分区执行情况
3、某节点的各分区(partition)的任务执行情况
在这里可以查看下start_time:如果差异很大说明计算资源紧缺,依次抢占了计算资源。
三、优化方案
1、资源切换
如果之前使用的是公共资源,那么可以切换为独享资源
2、Hash clustering
将数据提前进行shuffle和排序,在使用数据的过程中,读取数据后直接参与计算。这种模式非常适合产出后 后续节点多次按照相同key进行join或聚合的场景。
当然生成hash clustering table本身也是有代价的,在生辰阶段会进行一次额外的shuffle。
执行方法示例:
alter table s_auction_auctions CLUSTERED by (acution_id) SORTED by (auction_id) into 1200 buckets;
3、设置任务执行时的map、reduce、join实例数
'odps.stage.mapper.num' : 1024
'odps.stage.joiner.num' : 2048
'odps.stage.reducer.num' : 2048
4、提早过滤不必要的数据
DAG中输入较多数据的节点(线较粗的),提早过滤没用的数据,让输入数据变少点。