本文为您介绍MaxCompute的包年包月作业优先级功能,并提供开启、设置和查看作业优先级的操作指导。
背景信息
MaxCompute的包年包月计算资源有限,在实际数据开发过程中,系统需要优先保障重要作业的计算资源。例如,系统必须在06:00点前产出某些数据,则需要保障产出这些数据的一系列作业(工作流)能够在运行时优先抢占到计算资源。
您可以通过MaxCompute设置使用包年包月计算资源Project的作业优先级,优先保障高优先级作业的计算资源。当高优先级作业启动时,可以抢占低优先级作业的计算资源。
概述
MaxCompute中的每个作业都有优先级(Priority),取值为0~9,数值越小,优先级越高。高优先级作业会先于低优先级作业获取计算资源。
需要注意:
MaxCompute只支持设置使用包年包月计算资源Project的作业优先级。
当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模板和Quota计划,详情请参见配置Quota。
操作步骤
登录MaxCompute控制台,在左上角选择地域。
在左侧导航栏,选择工作区 > 配额(Quota)管理。
在Quota管理页面,单击需要配置的一级Quota操作列的Quota配置。
在Quota计划页签,单击目标计划操作列的编辑。
在编辑Quota计划对话框,勾选目标二级Quota行中的开启优先级。
说明二级Quota类型为交互式时,开启优先级参数默认不可用。
单击确定。
排查作业优先级步骤如下:
统计作业优先级分布情况。
命令示例如下。
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运维中心,选择 ,查看作业。
排查作业优先级。
通过DataWorks提交的作业:如果作业设置了基线,您需要判断基线的合理性。如果基线不合理,删除基线。详情请参见基线管理。
不是通过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的基线管理功能详情请参见基线管理。
DataWorks的基线优先级为1、3、5、7或8,数值越大,优先级越高。当您通过DataWorks的基线管理功能设置MaxCompute作业优先级时,MaxCompute作业优先级=9-DataWorks基线优先级。
说明DataWorks临时查询,默认没有基线,发起的MaxCompute作业最低优先级为9。
DataWorks工作流,由于有默认基线优先级为1,所以发起的MaxCompute作业最低优先级为8。
通过DataWorks节点直接设置作业优先级。
该方式常用于设置临时查询作业的优先级。命令示例如下。
set odps.instance.priority=x; //x为优先级取值。
查看作业优先级
您可以在Logview 2.0页面的Json Summary页签,通过odps.instance.priority参数查看作业优先级。更多Logview 2.0操作请参见使用Logview 2.0查看作业运行信息。
Logview页面上XML显示的优先级不准确。对于使用按量计费的Project,以及没有开启优先级功能且使用包年包月计算资源的Project,即使XML中设置的优先级值不等于9,系统也会将其改为9,防止排队不公平。