Maxcompute作业诊断

作业流程图

作业运行状态对照

odedescription备注
1010Waiting for scheduling作业已提交,准备调度
1011Waiting for cluster resource等待作业资源
1012Waiting for concurrent task slot等待并发执行资源
1013Waiting for data replication等待数据复制
1014Waiting for execution slot等待执行资源
1015Waiting for cleaning up of previous task attempt等待清理执行历史完成
1020Waiting for execution等待作业处理
1030Preparing for execution准备进行作业处理
1032Task is executing作业处理中
1040Job has been submitted作业提交计算集群
1041Offline Job Waiting for runningFuxi作业等待执行
1042Offline Job is runningFuxi作业执行中
1044Offline Job is failedFuxi作业执行失败
1045Offline Job is succeedFuxi作业执行成功
1046Offline Job is cancelled by fuxiFuxi作业被取消
1050Task rerun重新执行()
1051Online Job Waiting for running作业以ServiceMode方式等待执行
1052Online Job is running作业以ServiceMode方式执行中
1054 Online Job is failed 作业以ServiceMode方式执行失败
1055Online Job is succeed 作业以ServiceMode方式执行成功
1056 Online Job is cancelled by fuxi 作业被取消
1060 Task key-path executing finished 作业关键路径处理完成
1062 Task key-path is finished Task关键路径处理完成
1065 Instance key-path is finished Instance关键路径处理完成
1070 Task execution is finished 作业处理完成
1080 Instance execution is finished Instance处理完成
1090Execution failed 执行失败
1210 SQLTask is initializing SQL作业初始化中
1220 SQLTask is compiling query SQL作业编译中
1230 SQLTask is optimizing query SQL作业优化中
1235 SQLTask is splitting data sources SQL作业优化中
1240 SQLTask is generating execution plan SQL作业生成执行计划中
1250SQLTask is running the plan on fuxiSQL作业调度执行中
1260 SQLTask is update meta information SQL作业更新元数据信息
1270 SQLTask is finishingSQL作业成功结束

常见问题诊断

编译阶段

作业处于编译阶段的特征是有 logview,但还没有执行计划。根据 logview 的子状态(SubStatusHistory)可以进一步细分为调度、优化、生成物理执行计划、数据跨集群复制等子阶段。

 

编译阶段的问题主要表现为在某个子阶段卡住,即作业长时间停留在某一个子阶段。下面将介绍作业停留在每个子阶段的可能原因和解决方法。

调度阶段

【特征】子状态为“Waiting for cluster resource”,作业排队等待被编译。

【该阶段作业卡住的可能原因 1 】计算集群资源紧缺。

【解决方法】查看计算集群的状态,需要等待计算集群的资源。

【该阶段作业卡住的可能原因 2 】编译资源池资源不够:可能有人不小心用脚本一次提交太多作业,把编译资源池占满了。

优化阶段

【特征】子状态为“SQLTask is optimizing query”,优化器正在优化执行计划。

【该阶段作业卡住的可能原因】执行计划复杂,需要等待较长时间做优化。

生成物理执行计划阶段

【特征】子状态为“SQLTask is generating execution plan”。

【该阶段作业卡住的可能原因 1 】读取的分区太多。每个分区需要去根据分区信息来决定处理方式,决定 split,并且会写到生成的执行计划中。

【解决方法】需要好好设计 SQL,减少分区的数量,包括:分区裁剪、筛除不需要读的分区、把大作业拆成小作业。

【该阶段作业卡住的可能原因 2 】小文件太多。ODPS 会根据文件大小决定 split,小文件多了会导致计算 split 的过程耗时增加。

产生小文件的原因主要有两个:

  1. 我们使用 Tunnel 上传数据时操作不正确(例如每上传一条数据就重新 new 一个 upload session)

对分区表进行 insert into 操作的时候,会在 partition 目录下面生成一个新文件。

【解决方法】

  1. 使用 TunnelBufferedWriter 接口,可以更简单的进行上传功能,同时避免小文件。
  2. 执行一次 alter table merge smallfiles; 让 odps 把小文件 merge 起来。

【注意】上面提到的“太多”不是指几十、几百个。基本都是要上万,上十万才会对生成物理执行计划的时间产生较大影响。

数据跨集群复制阶段

【特征】子状态列表里面出现多次“Task rerun”,result 里有错误信息“FAILED: ODPS-0110141:Data version exception”。作业看似失败了,实际还在执行,说明作业正在做数据的跨集群复制。

【该阶段作业卡住的可能原因 1 】project 刚做集群迁移,往往前一两天有大量需要跨集群复制的作业。

【解决方法】这种情况是预期中的跨集群复制,需要用户等待。

【该阶段作业卡住的可能原因 2 】可能是作业提交错集群,或者是中间 project 做过迁移,分区过滤没做好,读取了一些比较老的分区。

【解决方法】

  1. 检查作业提交的集群是否正确。

用户可以通过 Logview1.0 点击 Status->System Info,或 Logview2.0 任务详情页左侧的 BasicInfo 查看作业提交的集群。

 

  1. 过滤掉不必要读取的老分区。

执行阶段

【特征】logview 的 detail 界面有执行计划(执行计划没有全都绿掉),且作业状态还是 Running。

执行阶段卡住或执行时间比预期长的主要原因有等待资源,数据倾斜,UDF 执行低效,数据膨胀等等,下面将具体介绍每种情况的特征和解决思路。

等待资源

【特征】instance 处于 Ready 状态,或部分 instance 是 Running,部分是 Ready 状态。需要注意的是,如果 instance 状态是 Ready 但有 debug 历史信息,那么可能是 instance fail 触发重试,而不是在等待资源。

【解决思路】

  1. 确定排队状态是否正常。

可以通过 logview 的排队信息“Queue”看作业在队列的位置;

或着通过 BCC 查看 project 当前的 quota 组作业信息、系统资源的的使用情况和历史曲线等等。

 

 

如果某项资源的使用率已经接近甚至超过配额了,那么证明 quota 组资源紧张,作业有排队是正常的。作业的调度顺序不仅与作业提交时间、优先级有关,还和作业所需内存或CPU资源大小能否被满足有关,因此合理设置作业的参数很重要

  1. 查看 quota 组中运行的作业。

可能会有人不小心提交了低优先级的大作业(或批量提交了很多小作业),占用了太多的资源,可以和作业的 owner 协商,让他先把作业 kill 掉,把资源让出来。

  1. 考虑去其他 quota 组的 project 跑。

只要有权限,是可以在别的 project 下访问另一个 project 的表的。当然,有可能会存在跨集群复制。

  1. 找 PE 扩容(从其他 quota 组调整资源过来)。普通用户请联系 project owner 或者 BU ODPS 接口人,由他们跟进调整资源或扩容需求。

资源组的配额一般都是经过多方考虑设置的,除非你的集群长期资源不足,否则一般不好申请。而且如果你的水位没到 MAX,又没有资源的话,很可能其他 quota 组也忙得不行。

数据倾斜

【特征】task 中大多数 instance 都已经结束了,但是有某几个 instance 却迟迟不结束(长尾)。如下图中大多数(358个)instance 都结束了,但是还有 18 个的状态是 Running,这些 instance 运行的慢,可能是因为处理的数据多。

【解决方法】需要找到造成数据倾斜的具体位置,对症下药。下面列出了定位长尾实例的常用方法:

  1. 利用 MaxCompute Studio 的作业执行图及作业详情功能来分析作业运行情况,定位到长尾实例,找到导致长尾的数据来源。
  2. 利用 Logveiw2.0 查看任务执行图和 instance 运行情况来定位长尾实例。

在确定造成数据倾斜的实例、数据来源等信息后,用户需要针对性的对代码甚至算法做一定的修改。

UDF执行低效

这里的 UDF 泛指各种用户自定义的扩展,包括UDF,UDAF,UDTF,UDJ,UDT等。

【特征】某个 task 执行效率低,且该 task 中有用户自定义的扩展。甚至是 UDF 的执行超时报错:“Fuxi job failed - WorkerRestart errCode:252,errMsg:kInstanceMonitorTimeout, usually caused by bad udf performance”。

【排查方法】任务报错时,可以在 MaxCompute Studio 中快速通过 DAG 图判断报错的 task 中是否包含 UDF。如下图,可以看到报错的task R4_3 包含用户使用 Java 语言编写的 UDF。双击 R4_3,展开 operator 视图,可以看到该 task 包含的所有 UDF 名称。

 

此外,在 task 的 stdout 日志里,UDF 框架会打印 UDF 输入的记录数、输出记录数、以及处理时间,如下图。通过这些数据可以看出 UDF 是否有性能问题。一般来讲,正常情况 Speed(records/s) 在百万或者十万级别,如果降到万级别,那么基本上就有性能问题了。 

 

【解决思路】当有性能问题时,可以按照下面这些方法进行排查和优化:

  1. 检查 UDF 是否有 bug。
  2. 检查 UDF 函数是否与内置函数同名
  3. 使用内置函数代替 UDF。
  4. 将 UDF 函数进行功能拆分,部分用内置函数替换,内置函数无法实现的再用 UDF
  5. 优化 UDF 的 evaluate 方法。
  6. 预估 UDF 的执行时间。
  7. 调整内存参数。

数据膨胀

【特征】task 的输出数据量比输入数据量大很多。

比如 1G 的数据经过处理,变成了 1T,在一个 instance 下处理 1T 的数据,运行效率肯定会大大降低。输入输出数据量体现在 Task 的 I/O Record 和 I/O Bytes 这两项:

 

 

【解决思路】

检查代码是否有 bug

  • JOIN 条件是不是写错了,变成笛卡尔积了;
  • UDTF 是不是有问题,输出了太多数据。

 检查 Aggregation 引起的数据膨胀

因为大多数 aggregator 是 recursive 的,中间结果先做了一层 merge,中间结果不大,而且大多数 aggregator 的计算复杂度比较低,即使数据量不小,也能较快完成。所以通常情况下这些操作问题不大,如:

  • select 中使用 aggregation 按照不同维度做 distinct,每一次 distinct 都会使数据做一次膨胀;
  • 使用 Grouping Sets (CUBE and ROLLUP) ,中间数据可能会扩展很多倍。

但是,有些操作如 collect_list、median 操作需要把全量中间数据都保留下来,可能会产生问题。

避免join引起的数据膨胀

比如:两个表 join,左表是人口数据,数据量很大,但是由于并行度足够,效率可观。右表是个维表,记录每种性别对应的一些信息(比如每种性别可能的坏毛病),虽然只有两种性别,但是每种都包含数百行。那么如果直接按照性别来 join,可能会让左表膨胀数百倍。要解决这个问题,可以考虑先将右表的行做聚合,变成两行数据,这样 join 的结果就不会膨胀了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值