MaxCompute后付费消费突增排查

在使用MaxCompute开发过程中会产生费用,如果平时每日消费比较平稳,某段时间的费用增长翻倍。在排除业务增长的情况下,可以进行费用分析,排查导致费用突增的项目、作业是哪些,进而及时优化和调整作业,优化成本。本文为您介绍如何结合账单详情和MaxCompute元数据服务(Information Schema)排查MaxCompute后付费消费突增。

背景信息

本文排查MaxCompute后付费消费突增总体思路如下:

  1. 通过费用中心确认费用超出预期的日期,然后确认当天具体是哪个项目中的哪个计费项产生了高额费用。

  2. 分析具体的消费上涨原因:

    • 如果是计算费用超出预期,您可以通过Information Schema视图中的TASKS_HISTORY数据统计作业量和TOP费用作业。

    • 如果是存储费用高出预期,您可以通过下载用量明细分析存储费用变化。

    • 如果是公网下行流量费用高出预期,您可以通过Information Schema视图中的TUNNELS_HISTORY数据统计公网下行流量费用变化。

步骤一:获取Information Schema服务

自2024年03月01日开始,MaxCompute停止对新增项目自动安装项目级别Information Schema,即新增的项目默认没有项目级别Information Schema的Package。若您有查元数据的业务,您可以查询租户级别的Information Schema,以便获取更全的信息。租户级别Information Schema的具体使用说明请参见租户级别Information Schema

对于存量MaxCompute项目,在您开始使用Information Schema服务前,需要以项目所有者(Project Owner)或具备Super_Administrato管理角色的RAM用户身份安装Information Schema权限包,获得访问项目元数据的权限。更多为用户授权管理角色操作信息,请参见将角色赋予用户。安装方式有如下两种,更多关于Information Schema的功能及使用限制,请参见Information Schema概述

说明
  • 如果统计多个MaxCompute项目的元数据,您需要分别对各个MaxCompute项目安装Information Schema权限包。然后把各个MaxCompute项目的元数据的备份数据插入到同一个表中做集中统计分析。

  • 建议您使用租户级别Information Schema服务,便于查询当前用户所有项目的元数据信息以及使用历史信息。更多信息请参见租户级别Information Schema

(可选)步骤二:对除Project Owner外的用户授权

Information Schema的视图包含了项目级别的所有用户数据,默认项目所有者可以查看。如果项目内其他用户或角色需要查看,需要进行授权,请参见基于Package跨项目访问资源

授权语法如下。

grant <actions> on package Information_Schema.systables to user <user_name>;
grant <actions> on package Information_Schema.systables to role <role_name>;
  • actions:待授予的操作权限,取值为Read。

  • user_name:已添加至项目中的阿里云账号或RAM用户。

    您可以通过MaxCompute客户端执行list users;命令获取用户账号。

  • role_name:已添加至项目中的角色。

    您可以通过MaxCompute客户端执行list roles;命令获取角色名称。

授权示例如下。

grant read on package Information_Schema.systables to user RAM$Bob@aliyun.com:user01;

(可选)步骤三:下载并备份元数据

MaxCompute对项目内已完成的作业历史,保留近14天数据。如果您时常有查询14天以前的数据需求,建议定时备份元数据至您的项目中。如果您更多是临时查询14天以内的作业运行历史,可以忽略此步骤。

  1. 登录MaxCompute客户端或使用SQL分析连接,执行如下命令创建元数据备份表。

    --project_name为MaxCompute项目名称。
    --创建tasks_history备份表。
    create table if not exists <project_name>.tasks_history
    (
        task_catalog STRING
        ,task_schema STRING
        ,task_name STRING
        ,task_type STRING
        ,inst_id STRING
        ,status STRING
        ,owner_id STRING
        ,owner_name STRING
        ,result STRING
        ,start_time DATETIME
        ,end_time DATETIME
        ,input_records BIGINT
        ,output_records BIGINT
        ,input_bytes BIGINT
        ,output_bytes BIGINT
        ,input_tables STRING
        ,output_tables STRING
        ,operation_text STRING
        ,signature STRING
        ,complexity DOUBLE
        ,cost_cpu DOUBLE
        ,cost_mem DOUBLE
        ,settings STRING
        ,ds STRING
    );
    --创建tunnels_history备份表
    create table if not exists <project_name>.tunnels_history
    (
    tunnel_catalog  string
    ,tunnel_schema   string
    ,session_id      string
    ,operate_type    string
    ,tunnel_type     string
    ,request_id      string
    ,object_name     string
    ,partition_spec  string
    ,data_size       bigint
    ,block_id        bigint
    ,offset          bigint
    ,length          bigint
    ,owner_id        string 
    ,owner_name      string 
    ,start_time      datetime
    ,end_time        datetime 
    ,client_ip       string 
    ,user_agent      string 
    ,object_type     string 
    ,columns         string 
    ,ds  string
    );
  2. 进入DataWorks数据开发界面,创建ODPS SQL节点(history_backup)并配置定时调度,用于定时将数据写入备份表tasks_history和tunnels_history。完成后单击左上角保存图标保存。

    创建ODPS SQL节点操作,请参见创建ODPS SQL节点

    ODPS SQL节点运行的命令示例如下:

    --project_name为MaxCompute项目名称。 
    use <project_name>; 
    --备份tasks_history。
    insert into table <project_name>.tasks_history 
    select task_catalog,task_schema ,task_name,task_type STRING,inst_id,`status`,owner_id,owner_name,result,start_time,end_time,input_records,output_records,input_bytes,output_bytes,input_tables,output_tables,operation_text,signature,complexity,cost_cpu,cost_mem,settings,ds from information_schema.tasks_history where ds ='${datetime1}';
    --备份tunnels_history。
    insert into table <project_name>.tunnels_history 
    select tunnel_catalog,tunnel_schema,session_id,operate_type,tunnel_type,request_id,object_name,partition_spec,data_size,block_id,offset,length,owner_id,owner_name,start_time,end_time,client_ip,user_agent,object_type,columns,ds from information_schema.tunnels_history where ds ='${datetime1}';

    ${datetime1}为DataWorks的调度参数,您需要在ODPS SQL节点右侧,单击调度配置,在基础属性区域配置参数值为datetime1=${yyyymmdd}

    说明

    如果需要同时对多个MaxCompute项目的元数据进行统计分析,您可以创建多个ODPS SQL节点,将这些MaxCompute项目的元数据写入到同一张数据备份表中。

步骤四:通过费用中心分析高额消费项目和计费项

进入费用中心请参见进入费用中心,在费用中心可以通过如下方式分析高额消费项目和计费项。

  • 账单详情页面的明细账单页签下,按统计项实例统计周期按天进行查看,查找产生高额费用的项目(实例ID。如果有明显的某个项目消费与预期不符,则针对该项目进行分析。image

  • 账单详情页面的明细账单页签下,按统计项计费项统计周期按天进行查看,查找产生高额费用的计费项。可以通过实例ID搜索指定的项目,针对具体项目分析具体的高额计费项。image

  • 成本分析页面也可以较为直观的查找出消费上涨的计费项。

    image

步骤五:具体消费上涨原因排查

对高额消费项目和计费项针对性分析排查消费上涨原因。

SQL作业计算费用高出预期

SQL作业整体消费较高(包含外部表作业),可能是单条作业消费异常,也可能由于重复执行或调度属性配置不合理造成作业量突增。

  1. 可以通过查询消费异常作业的实例ID(inst_id),查看具体的执行信息。

    1. 登录MaxCompute客户端或使用SQL分析连接,使用use命令切换到步骤四找出的高额消费的项目,通过TASKS_HISTORY查询作业消费情况,命令示例如下。

      --开启2.0数据类型开关。2.0数据类型详情,请参见2.0数据类型版本。
      set odps.sql.decimal.odps2=true;
      select  
      inst_id ---实例id
      ,input_bytes ---数据输入量(
      ,complexity
      ,cast(input_bytes/1024/1024/1024 * complexity * 0.3 as DECIMAL(18,5) ) cost_sum
      ,get_json_object(settings, "$.SKYNET_ID") SKYNET_ID ---DataWorks调度任务ID
      from    information_schema.tasks_history 
      --如果是查询14天前的元数据,需要查询通过步骤三备份的表,表名为<project_name>.tasks_history
      where   task_type = 'SQL' OR task_type = 'SQLRT'
      AND ds = '待查询的日期分区'
      ORDER BY cost_sum DESC
      LIMIT 10000
      ;
      说明

      • 一次SQL计算费用 = 计算输入数据量×SQL复杂度×单价(0.3 元/GB)。

      • 示例中的task_type = 'SQL'表示SQL作业;task_type = 'SQLRT'表示SQL查询加速作业。

    2. 查看消费较高SQL作业的SKYNET_ID(DataWorks调度任务ID)。

      • 如果有ID,请在DataWorks上查看节点具体执行情况。

      • 如果没有ID,说明此任务不是通过DataWorks调度节点发起的任务,可以根据inst_id,查看具体的执行信息,命令示例如下。

        select operation_text from information_schema.tasks_history 
        where ds='<任务执行所在日期分区>' and inst_id='<inst_id>';
  2. 查找运行数量较多的重复作业。

登录MaxCompute客户端或使用SQL分析连接,使用use命令切换到步骤四找出的高额消费的项目,通过TASKS_HISTORY查询重复运行的作业,命令示例如下。

--分析作业增长趋势。
SELECT  signature
        ,ds
        ,COUNT(*) AS tasknum
FROM    information_schema.tasks_history 
--如果是查询14天前的元数据,需要查询通过步骤三备份的表,表名为<project_name>.tasks_history
where   task_type = 'SQL' OR task_type = 'SQLRT'
AND ds >= '待查询的日期分区'
GROUP BY ds
         ,signature
ORDER BY tasknum DESC
LIMIT   10000
;

--确认异常的signature,查看对应的SQL作业近期执行情况
SELECT  *
FROM    information_schema.tasks_history 
--如果是查询14天前的元数据,需要查询通过步骤三备份的表,表名为<project_name>.tasks_history
where   signature = '异常signature'
AND ds >= '待查询的日期分区'
;

Spark计算费用高出预期

Spark作业整体消费较高,可以通过查询消费异常的作业inst_id,查看具体的执行信息。

  1. 登录MaxCompute客户端或使用SQL分析连接,使用use命令切换到步骤四找出的高额消费的项目,通过TASKS_HISTORY查询作业消费情况,命令示例如下。

    --开启2.0数据类型开关。2.0数据类型详情,请参见2.0数据类型版本。
    set odps.sql.decimal.odps2=true;
    select  inst_id --实例id
    ,cost_cpu --作业CPU消耗(100表示1 core×s。例如:10 core运行5s,cost_cpu为10×100×5=5000)。
    ,cast(cost_cpu/100/3600 * 0.66 as DECIMAL(18,5) ) cost_sum
    from    information_schema.tasks_history 
    --如果是查询14天前的元数据,需要查询通过步骤三备份的表,表名为<project_name>.tasks_history
    where   task_type = 'CUPID' and status='Terminated'
    AND ds = '待查询的日期分区'
    ORDER BY cost_sum DESC
    LIMIT 10000
    ;
    说明
    • Spark作业当日计算费用 = 当日总计算时×单价(0.66 元/计算时)。

    • task_type = 'CUPID'表示Spark作业。

  2. 根据inst_id,查看具体的执行信息,命令示例如下。

    select operation_text from information_schema.tasks_history 
    where ds='任务执行所在日期分区' and inst_id='<inst_id>';

MapReduce作业消费高出预期

MapReduce作业整体消费较高,可以通过查询消费异常的作业inst_id,查看具体的执行信息。

  1. 登录MaxCompute客户端或使用SQL分析连接,使用use命令切换到步骤四找出的高额消费的项目,通过TASKS_HISTORY查询作业消费情况,命令示例如下。

    --开启2.0数据类型开关。2.0数据类型详情,请参见2.0数据类型版本。
    set odps.sql.decimal.odps2=true;
    select  inst_id --实例id
    ,cost_cpu --作业CPU消耗(100表示1 core×s。例如:10 core运行5s,cost_cpu为10×100×5=5000)。
    ,cast(cost_cpu/100/3600 * 0.46 as DECIMAL(18,5) ) cost_sum
    from    information_schema.tasks_history 
    --如果是查询14天前的元数据,需要查询通过步骤三备份的表,表名为<project_name>.tasks_history
    where   task_type = 'LOT' and status='Terminated'
    AND ds = '待查询的日期分区'
    ORDER BY cost_sum DESC
    LIMIT 10000
    ;
    说明
    • MapReduce作业当日计算费用 = 当日总计算时×单价(0.46 元/GB)。

    • task_type = 'LOT'表示MapReduce作业。

  2. 根据inst_id,查看具体的执行信息,命令示例如下。

    select operation_text from information_schema.tasks_history 
    where ds='任务执行所在日期分区' and inst_id='<inst_id>';

存储费用高出预期

需要使用用量明细查询存储费用。

  1. 下载用量明细,详情请参见下载用量明细

  2. 上传用量明细,详情请参见上传用量明细数据至MaxCompute

  3. 通过SQL分析,详情请参见MaxCompute账单用量明细分析

公网下行流量费用高出预期

公网下行流量整体消费较高,可以按照如下操作分析具体哪段时间哪个类别的下载费用较高。

登录MaxCompute客户端或使用SQL分析连接,使用use命令切换到步骤四找出的高额消费的项目,通过TUNNELS_HISTORY查询下载消费情况,命令示例如下。

--开启2.0数据类型开关。2.0数据类型详情,请参见2.0数据类型版本。
set odps.sql.decimal.odps2=true;
SELECT  ds
        ,operate_type
        ,SUM(CAST(data_size / 1024 / 1024 / 1024 * 0.8 AS DECIMAL(18,5))) download_fee
FROM    information_schema.tunnels_history
WHERE   operate_type = 'DOWNLOADLOG'
OR      operate_type = 'DOWNLOADINSTANCELOG'
AND     ds >= '待查询的日期分区'
GROUP BY ds
         ,operate_type
ORDER BY download_fee DESC
;
说明

一次下载费用=下载数据量×单价(0.8 元/GB)。

按照执行结果也可以分析出某个时间段内的下载费用走势。另外可以通过tunnel show history命令查看具体历史信息,具体命令请参见Tunnel命令image

更多信息

如果您想了解更多关于费用成本优化的文章,请参见成本优化概述