本文为您介绍MaxCompute的包年包月作业优先级功能,并提供开启、设置和查看作业优先级的操作指导。

背景信息

MaxCompute的包年包月计算资源有限,在实际数据开发过程中,系统需要优先保障重要作业的计算资源。例如,系统必须在06:00点前产出某些数据,则需要保障产出这些数据的一系列作业(工作流)能够在运行时优先抢占到计算资源。

您可以通过MaxCompute设置使用包年包月计算资源Project的作业优先级,优先保障高优先级作业的计算资源。当高优先级作业启动时,可以抢占低优先级作业的计算资源。

概述

MaxCompute中的每个作业都有优先级(Priority),取值为0~9,数值越小,优先级越高。高优先级作业会先于低优先级作业获取计算资源。

需要注意:
  • MaxCompute只支持设置使用包年包月计算资源Project的作业优先级。
  • 当Project的作业优先级功能未开启时,除以下作业外,其他作业的默认优先级为9。
    • PAI算法作业,默认优先级为1。
    • *_dev命名的作业,默认优先级为3。

开启优先级功能

仅Project Owner或拥有Super_Administrator角色的用户可以执行如下命令打开优先级功能开关。
setproject odps.instance.priority.enable=true;

优先级功能开启后,使用包年包月计算资源Project的所有作业的优先级会立即生效。如果您设置的优先级不合理,可能导致作业排队混乱。

注意 建议您先通过Information Schema排查存量作业的优先级,并根据需要将非9的作业优先级设置为9,然后再打开优先级功能开关。
排查作业优先级步骤如下:
  1. 统计作业优先级分布情况。
    命令示例如下。
    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任务,可忽略。
  2. 定位优先级非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_nameuser_agent字段进行排查。
    • SKYNET_ONDUTY:表示周期性作业。您可以进入DataWorks运维中心,选择周期任务运维 > 周期实例,查看作业。
  3. 排查作业优先级。
    • 通过DataWorks提交的作业:如果作业设置了基线,您需要判断基线的合理性。如果基线不合理,删除基线即可恢复默认优先级9。详情请参见基线管理
    • 不是通过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 {
            Account account = new AliyunAccount("accessId","accessKey");
            Odps odps = new Odps(account);
            String odpsUrl = "http://service.odps.aliyun.com/api"; // 公共云URL。
            odps.setEndpoint(odpsUrl);
            odps.setDefaultProject("xxxxxxxxxx");
            SQLTask task = new SQLTask();
            task.setName("adhoc_sql_task_1");
            task.setQuery("select count(*) from aa;");
            Instance instance = odps.instances().create(task, 5); // 5为作业优先级。
            LogView logView = new LogView(odps);
            System.out.println(logView.generateLogView(instance, 24)); // 打印Logview,用于查看Instance执行状态,非必须。
            instance.waitForSuccess(); // 等待Instance执行完成,非必须。
        }
    }
  • 通过DataWorks的基线管理功能设置作业优先级。

    该方式常用于保障某个周期性作业以及其上游作业优先产出数据。您可以通过基线管理功能集中设置整条数据链路上各个作业的优先级,无需单独处理每个作业。DataWorks的基线管理功能详情请参见基线管理

    DataWorks的基线优先级为1、3、5、7或8,数值越大,优先级越高。当您通过DataWorks的基线管理功能设置MaxCompute作业优先级时,MaxCompute作业优先级=9-DataWorks基线优先级。

  • 通过DataWorks节点直接设置作业优先级。
    该方式常用于设置临时查询作业的优先级。命令示例如下。
    set odps.instance.priority=x;
    //x为优先级取值。

查看优先级

您可以通过Logview查看作业优先级。Logview详情请参见使用Logview查看Job信息
  1. 在Logview页面,单击Detail
    Detail
  2. 在作业详细信息对话框中,单击JSONSummary页签,查看odps.instance.priority参数取值。 JOSNSummary
    说明 Logview页面上XML显示的优先级不准确。对于使用按量计费的Project,以及没有开启优先级功能且使用包年包月计算资源的Project,即使XML中设置的优先级值不等于9,系统也会将其改为9,防止排队不公平。
    XML