本文介绍MaxCompute作业优先级功能,并说明如何开启、设置及查看作业的优先级。
背景信息
MaxCompute的计算资源有限,在实际数据开发过程中,系统需要优先保障重要作业的计算资源。例如,系统必须在06:00前产出某些数据,则需要保障产出这些数据的一系列作业(工作流)能够在运行时优先抢占到计算资源。
这一需求可以通过设置使用计算资源的Project作业优先级实现,优先保障高优先级作业的计算资源,当高优先级作业启动时,可以抢占低优先级作业的计算资源。
优先级概述
MaxCompute中的每个作业都有优先级(Priority),取值为0~9,数值越小,优先级越高。高优先级作业会先于低优先级作业获取计算资源。
当Project的作业优先级功能未开启时,作业的默认优先级为9。PAI算法作业,默认优先级为1。
开启优先级
Project级别开启优先级
仅Project Owner或拥有Super_Administrator角色的用户可以执行如下命令打开优先级功能开关。
setproject odps.instance.priority.enable=true;
优先级功能开启后,使用计算资源Project的所有作业的优先级会立即生效。但是如果设置的优先级不合理,可能会导致作业排队混乱。
建议先通过Information Schema排查存量作业的优先级,并根据需要将非9的作业优先级设置为9,然后再打开优先级功能开关。
Quota级别开启优先级
优先级功能开启后,在此Quota上执行的作业优先级将生效,等同Project级别开启优先级。
开启前确认已创建Quota模板和Quota计划,详情请参见Configure quotas。
操作步骤
-
Log in to the MaxCompute console and select a region in the upper-left corner.
-
In the left-side navigation pane, choose .
-
On the Quotas page, click Quota Configuration in the Actions column for the target quota.
-
On the Quota Configuration page, select the Basic Configurations tab and click Edit Basic Configurations.
-
Select the Enable Priority option for the target level-2 quota.
Note二级QuotaType为Interactive时,开启优先级参数默认不可用。
-
Click OK.
排查作业优先级
-
统计作业优先级分布情况
命令示例如下:
SELECT get_json_object( REPLACE(settings, '.', '_') ,'$.odps_instance_priority' ) AS priority ,task_type ,COUNT(1) AS cnt FROM information_schema.tasks_history WHERE ds = '${bizdate}' -- bizdate为日期分区。 GROUP BY get_json_object( REPLACE(settings, '.', '_') ,'$.odps_instance_priority' ) ,task_type ORDER BY cnt DESC LIMIT 100 ;返回结果如下:
+----------+-----------+------------+ | priority | task_type | cnt | +----------+-----------+------------+ | 9 | SQL | 4 | | NULL | SQL | 1 | | 2 | SQL | 1 | +----------+-----------+------------+返回结果示例涉及NULL、2和9三种优先级。需要定位优先级为2和NULL的作业。NULL通常为DDL任务,可忽略。
-
定位优先级非9的作业。
命令示例如下:
SELECT inst_id ,owner_name ,task_name ,task_type ,settings FROM information_schema.tasks_history WHERE ds = '${bizdate}' AND get_json_object(REPLACE(settings, '.', '_'), '$.odps_instance_priority') = '${priority}' LIMIT 100 ;-
bizdate:取值为日期分区,例如20200517。
-
priority:取值为非9的优先级数值,例如2。
返回结果如下:
+---------+------------+-----------+-----------+----------+ | inst_id | owner_name | task_name | task_type | settings | +---------+------------+-----------+-----------+----------+ | 20200517160200907g4jm**** | ALIYUN$odps_dev_****@prod.trusteeship.aliyunid.com | console_query_task_158973132**** | SQL | {"SKYNET_ID": "21000041****", "odps.instance.priority": "2", "SKYNET_ONDUTY": "113058643178****", "user_agent": "JavaSDK Revision:33acd11 Version:0.30.9 JavaVersion:1.8.0_112 CLT(0.30.2 : 9da012b); Linux(/)", "biz_id": "210000416174_20200517_211843317416_210033365461_1_habai_test_1130586431784115_39419845061****", "SKYNET_NODENAME": "test_priority"} | +---------+------------+-----------+-----------+----------+-
SKYNET_ID:表示DataWorks的调度节点ID。如果返回结果中不包含该字段,表明该作业不是通过DataWorks提交,需要通过owner_name和user_agent字段排查。
-
SKYNET_ONDUTY:表示周期性作业。
-
-
排查作业优先级。
-
通过DataWorks提交的作业:如果作业设置了基线,需要判断基线的合理性。如果基线不合理,删除基线。详情请参见Baseline management。
-
不是通过DataWorks提交的作业:可以通过返回结果定位到具体责任人和代码,取消代码中设置的优先级,即可恢复默认优先级9。
-
设置优先级
设置作业优先级的方式如下:
-
方式一:运行MaxCompute客户端并进入Project空间,设置作业优先级。
该方式常用于设置临时查询作业的优先级。命令示例如下:
SET odps.instance.priority=values; -- values取值为0~9。 -
方式二:运行MaxCompute客户端并进入Project空间,将SQL作为参数传入,设置作业优先级。
该方式常用于设置临时查询作业的优先级。命令示例如下:
bin/odpscmd --config=xxx --project=xxx --instance-priority=x -e "<sql>" -
方式三:通过Java SDK设置作业优先级。
可以通过该方式自行设计优先级设置方法。详情请参见Java SDK介绍。命令示例如下:
import com.aliyun.odps.Instance; import com.aliyun.odps.LogView; import com.aliyun.odps.Odps; import com.aliyun.odps.OdpsException; import com.aliyun.odps.account.Account; import com.aliyun.odps.account.AliyunAccount; import com.aliyun.odps.task.SQLTask; public class OdpsPriorityDemo { public static void main(String args[]) throws OdpsException { // 阿里云账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM用户进行API访问或日常运维,请登录RAM控制台创建RAM用户 // 此处以把AccessKey 和 AccessKeySecret 保存在环境变量为例说明。您也可以根据业务需要,保存到配置文件里 // 强烈建议不要把 AccessKey 和 AccessKeySecret 保存到代码里,会存在密钥泄漏风险 Account account = new AliyunAccount(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"),System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET")); Odps odps = new Odps(account); // 公共云URL。 String odpsUrl = "http://service.odps.aliyun.com/api"; odps.setEndpoint(odpsUrl); odps.setDefaultProject("xxxxxxxxxx"); SQLTask task = new SQLTask(); task.setName("adhoc_sql_task_1"); task.setQuery("select count(*) from aa;"); // 5为作业优先级。 Instance instance = odps.instances().create(task, 5); LogView logView = new LogView(odps); // 打印Logview,用于查看Instance执行状态,非必须。 System.out.println(logView.generateLogView(instance, 24)); // 等待Instance执行完成,非必须。 instance.waitForSuccess(); } } -
方式四:通过DataWorks的基线管理功能设置作业优先级。
该方式常用于保障某个周期性作业以及其上游作业优先产出数据。可以通过基线管理功能集中设置整条数据链路上各个作业的优先级,无需单独处理每个作业。DataWorks的基线管理功能详情请参见Baseline management。
DataWorks的基线优先级为1、3、5、7或8,数值越大,优先级越高。当通过DataWorks的基线管理功能设置MaxCompute作业优先级时,MaxCompute作业优先级=9-DataWorks基线优先级。
NoteDataWorks临时查询,默认没有基线,发起的MaxCompute作业最低优先级为9。
DataWorks工作流,由于有默认基线优先级为1,所以发起的MaxCompute作业最低优先级为8。
-
方式五:通过DataWorks节点直接设置作业优先级。
该方式常用于设置临时查询作业的优先级。命令示例如下。
set odps.instance.priority=x; -- x为优先级取值。
查看优先级
You can view the job priority on the Json Summary tab of the LogView V2.0 page by checking the odps.instance.priority parameter. For more information about LogView V2.0, see Use LogView V2.0 to view job information.
Logview页面上XML显示的优先级不准确。对于没有开启优先级功能的Project,即使XML中设置的优先级值不等于9,系统也会将其改为9,防止排队不公平。