本文为您介绍如何分析MaxCompute账单。

背景信息

MaxCompute是一款大数据分析平台,其计算资源的计费方式分为包年包月和按量计费两种,产品每天会以Project为维度进行计费(账单会在第二天上午6点前生成)。关于MaxCompute计量计费说明,详情请参见计费方式

我们会在数据开发阶段或者在产品上线前夕发布账单波动(通常情况下为消费增长)信息。您可以通过自助的方式来分析账单波动情况,再对自己的作业进行优化。您可以在阿里云费用中心下载阿里云所有收费产品的费用明细。账单的获取和下载,请参见查看账单详情
说明 通常您需要使用主账号查看账单详情。如果您需要使用子账号查看账单信息,请首先参考费用中心RAM配置策略选择需要的策略对子账号授权。

账单字段说明

账单明细字段如下:
  • 项目编号:当前账号或子账号对应的主账号的MaxCompute Project列表。
  • 计量信息编号:以存储、计算、上传和下载的任务ID为计费信息编号,SQL为InstanceId,上传和下载为Tunnel SessionId。
  • 数据分类:Storage(存储)、ComputationSql(计算)、UploadIn(内网上传)、UploadEx(外网上传)、DownloadIn(内网下载)、DownloadEx(外网下载)。按照计费规则其中只有红色部分为实际计费项目。
  • 存储(Byte):每小时读取的存储量,单位为Byte。
  • 开始时间/结束时间:按照实际作业执行时间进行计量,只有存储是按照每个小时取一次数据。
  • SQL读取量(Byte):SQL计算项,每一次SQL执行时SQL的Input数据量,单位为Byte。
  • SQL复杂度(Byte):每次执行SQL的复杂度,为SQL计费因子之一。
  • 公网上行流量(Byte)、公网下行流量(Byte):分别为公网上传和下载的数据量,单位Byte。
  • MR/Spark作业计算(CoreSecond):MapReduce/Spark作业的计算时单位为CoreSecond,需要转换为计算时Hour。
  • SQL读取量_访问OTS(Byte)、SQL读取量_访问OSS(Byte):外部表实施收费后的读取数据量,单位Byte。
  • 计算资源规格(按量计费):对应计量信息所在项目所属的计算资源规格,若值为NULL,则表示按量计费标准版;若值为OdpsDev,则表示按量计费开发者版。
  • 计算资源规格(包年包月):对应计量信息所在项目所属的计算资源规格。若值为NULL,则表示包年包月标准版;若值为OdpsPlus160CU150TBOdpsPlus320CU300TBOdpsPlus600CU500TB,则分别表示存储密集型160套餐、存储密集型320套餐,存储密集型600套餐。
  • DataWorks调度任务ID:计量作业在DataWorks上的调度节点ID。若值NULL,则表示非DataWorks调度节点提交的Job;若值为一串数字ID,则表示Job对应DataWorks调度节点ID。您可以在DataWorks对应的项目中使用该ID搜索到具体任务。

上传账单明细至MaxCompute

  1. 确认CSV文件数据,尤其是列分隔符等。数据以逗号分隔,且单元格值都带有双引号。
  2. 对数据进行预处理,以方便使用Tunnel等工具。将文档所有双引号替换为空,单击全部替换
  3. 创建MaxCompute表maxcomputefee,存储下载的消费明细。
    DROP TABLE IF EXISTS maxcomputefee ;
    CREATE TABLE IF NOT EXISTS maxcomputefee 
    (
        projectid STRING COMMENT '项目编号'
        ,feeid STRING COMMENT '计费信息编号'
        ,type STRING COMMENT '数据分类,包括Storage、ComputationSQL、DownloadEx等'
        ,storage BIGINT COMMENT '存储(Byte)'
        ,endtime DATETIME COMMENT '结束时间'
        ,computationsqlinput BIGINT COMMENT 'SQL/交互式分析 读取量(Byte)'
        ,computationsqlcomplexity DOUBLE COMMENT 'sql复杂度'
        ,uploadex BIGINT COMMENT '公网上行流量Byte'
        ,download BIGINT COMMENT '公网下行流量Byte'
        ,cu_usage DOUBLE COMMENT 'MR计算时*second'
        ,input_ots BIGINT COMMENT '访问OTS的数据输入量'
        ,input_oss BIGINT COMMENT '访问OSS的数据输入量'
        ,starttime DATETIME COMMENT '开始时间'
        ,source_type String COMMENT '计算资源'
        ,source_id String COMMENT 'DataWorks调度任务ID'
    );
  4. Tunnel上传数据,Tunnel的配置详情请参见Tunnel命令参考
    odps@ sz_mc>tunnel upload /Users/yangyi/Desktop/ODPS_2019-01-12_2019-01-14.csv maxcomputefee -c "UTF-8" -h "true" -dfp "yyyy-MM-dd HH:mm:ss";
    说明 用户也可以通过DataWorks数据导入的功能来执行此操作,具体请参见数据集成导入导出数据
  5. 使用如下语句验证数据。
    SELECT * FROM maxcomputefee limit 10;

通过SQL分析账单数据

  1. 分析SQL费用。云上用户使用MaxCompute,95%的用户通过SQL即可满足需求,SQL也在消费增长中占了很大比例。
    说明 一次SQL计算费用=计算输入数据量*SQL复杂度*单价(0.3元/GB)
    --分析SQL消费,按照sqlmoney行排行。
    SELECT  to_char(endtime,'yyyymmdd') as ds,feeid as instanceid
            ,projectid
            ,computationsqlcomplexity  --复杂度
            ,SUM((computationsqlinput / 1024 / 1024 / 1024)) as computationsqlinput  --数据输入量(GB)
            ,SUM((computationsqlinput / 1024 / 1024 / 1024)) * computationsqlcomplexity * 0.3 AS sqlmoney
    FROM    maxcomputefee
    WHERE   TYPE = 'ComputationSql'
    AND to_char(endtime,'yyyymmdd') >= '20190112'
    GROUP BY to_char(endtime,'yyyymmdd'),feeid
             ,projectid
             ,computationsqlcomplexity
    ORDER BY sqlmoney DESC 
    LIMIT   10000
    ;
    查询结果如下。
    根据查询结果可以得到以下结论:
    • 大作业可以减小数据读取量、降低复杂度来优化费用成本。
    • 可以按照ds字段(按照天)进行汇总,分析某个时间段内的SQL消费金额走势。例如利用本地excel或云上QuickBI等工具绘制折线图等方式,更直观的反应作业的趋势。
    • 根据执行结果可以定位到需要优化的点,方法如下:
      1. 获取具体的InstanceId。
        在客户端或者DataWorks中脚本执行wait instanceid;命令查看具体作业和SQL。
      2. 在浏览器中打开Logview的URL地址。
        关于Logview的介绍请参见使用Logview查看Job信息
      3. 从Logview中获取DataWorks节点名称。
        在Logview中打开SourceXML可以查看到具体执行信息,例如SKYNET_NODENAME表示DataWorks的节点名称(只有被调度系统执行的作业才有值,临时查询为空,如下图所示)。获得节点名称后,可以快速地在DataWorks上找到该节点进行优化或查看责任人,如下图所示。
  2. 分析作业增长趋势。通常费用的增长是由于重复执行或调度属性配置不合理造成的作业量暴涨。
    --分析作业增长趋势。
    SELECT  TO_CHAR(endtime,'yyyymmdd') AS ds
            ,projectid
            ,COUNT(*) AS tasknum
    FROM    maxcomputefee
    WHERE   TYPE = 'ComputationSql'
    AND     TO_CHAR(endtime,'yyyymmdd') >= '20190112'
    GROUP BY TO_CHAR(endtime,'yyyymmdd')
             ,projectid
    ORDER BY tasknum DESC
    LIMIT   10000
    ;
    执行结果如下。从执行结果可以看出12~14日提交到MaxCompute且执行成功的作业数的波动趋势。
  3. 分析存储费用。
    说明 存储费用的计费规则相对复杂。明细中是按每个小时取一次得出的数据。按照MaxCompute存储计费规则,会先整体24小时求和,再将平均之后的值进行阶梯收费。详情请参见存储费用(按量计费)
    --分析存储费用。
    SELECT  t.ds
            ,t.projectid
            ,t.storage
            ,CASE    WHEN t.storage < 0.5 THEN 0.01
                     WHEN t.storage >= 0.5 AND t.storage <= 10240 THEN t.storage*0.0072
                     WHEN t.storage > 10240 AND t.storage <= 102400 THEN (10240*0.0072+(t.storage-10240)*0.006)
                     WHEN t.storage > 102400  THEN (10240*0.0072+(102400-10240)*0.006+(t.storage-102400)*0.004)
            END storage_fee
    FROM    (
                SELECT  to_char(starttime,'yyyymmdd') as ds
                        ,projectid
                        ,SUM(storage/1024/1024/1024)/24 AS storage
                FROM    maxcomputefee
                WHERE   TYPE = 'Storage'
                and to_char(starttime,'yyyymmdd') >= '20190112'
                GROUP BY to_char(starttime,'yyyymmdd')
                         ,projectid
            ) t
    ORDER BY storage_fee DESC
    ;
    执行结果如下。根据执行结果可以分析得出如下结论:
    • 存储在12日有一个增长的过程,但在14日出现降低。
    • 存储优化,建议为表设置生命周期,删除长期不使用的临时表等。
  4. 分析下载费用。
    对于公网或者跨Region的数据下载,MaxCompute将按照下载的数据量进行计费。
    说明 计费公式为一次下载费用=下载数据量*单价(0.8元/GB)
    --分析下载消费明细。
    SELECT  TO_CHAR(starttime,'yyyymmdd') AS ds
            ,projectid
            ,SUM((download/1024/1024/1024)*0.8) AS download_fee
    FROM    maxcomputefee
    WHERE   type = 'DownloadEx'
    AND     TO_CHAR(starttime,'yyyymmdd') >= '20190112'
    GROUP BY TO_CHAR(starttime,'yyyymmdd')
             ,projectid
    ORDER BY download_fee DESC
    ;
    按照执行结果也可以分析出某个时间段内的下载费用走势。另外可以通过tunnel show history查看具体历史信息,具体命令详见Tunnel命令参考
  5. 分析MapReduce作业消费。
    说明 MapReduce任务当日计算费用=当日总计算时*单价(0.46元)
    --分析MapReduce作业消费。
    SELECT  TO_CHAR(starttime,'yyyymmdd') AS ds
            ,projectid
            ,(cu_usage/3600)*0.46 AS mr_fee
    FROM    maxcomputefee
    WHERE   type = 'MapReduce'
    AND     TO_CHAR(starttime,'yyyymmdd') >= '20190112'
    GROUP BY TO_CHAR(starttime,'yyyymmdd')
             ,projectid
             ,cu_usage
    ORDER BY mr_fee DESC
    ;
  6. 分析外部表作业(OTS和OSS)。
    说明 一次SQL外部表计算费用=计算输入数据量*SQL复杂度(1)*单价(0.03元/GB)
    --分析OTS外部表SQL作业消费。
    SELECT  TO_CHAR(starttime,'yyyymmdd') AS ds
            ,projectid
            ,(input_ots/1024/1024/1024)*1*0.03 AS ots_fee
    FROM    maxcomputefee
    WHERE   type = 'ComputationSql'
    AND     TO_CHAR(starttime,'yyyymmdd') >= '20190112'
    GROUP BY TO_CHAR(starttime,'yyyymmdd')
             ,projectid
             ,input_ots
    ORDER BY ots_fee DESC
    ;
    
    --分析OSS外部表SQL作业消费。
    SELECT  TO_CHAR(starttime,'yyyymmdd') AS ds
            ,projectid
            ,(input_oss/1024/1024/1024)*1*0.03 AS ots_fee
    FROM    maxcomputefee
    WHERE   type = 'ComputationSql'
    AND     TO_CHAR(starttime,'yyyymmdd') >= '20190112'
    GROUP BY TO_CHAR(starttime,'yyyymmdd')
             ,projectid
             ,input_oss
    ORDER BY ots_fee DESC
    ;
  7. 分析Lightning查询费用。
    说明 一次Lightning查询费用 = 查询输入数据量*单价(0.03元/GB)
    SELECT  to_char(endtime,'yyyymmdd') as ds,feeid as instanceid
            ,projectid
            ,computationsqlcomplexity
            ,SUM((computationsqlinput / 1024 / 1024 / 1024)) as computationsqlinput
            ,SUM((computationsqlinput / 1024 / 1024 / 1024)) * computationsqlcomplexity * 0.03 AS sqlmoney
    FROM    maxcomputefee
    WHERE   TYPE = 'LightningQuery'
    --AND to_char(endtime,'yyyymmdd') >= '20190112'
    GROUP BY to_char(endtime,'yyyymmdd'),feeid
             ,projectid
             ,computationsqlcomplexity
    ORDER BY sqlmoney DESC 
    LIMIT   10000
    ;
  8. 分析Spark计算费用。
    说明 Spark任务当日计算费用 = 当日总计算时*单价(0.66元/计算时)
    --分析Spark作业消费。
    SELECT  TO_CHAR(starttime,'yyyymmdd') AS ds
            ,projectid
            ,(cu_usage/3600)*0.66 AS mr_fee
    FROM    maxcomputefee
    WHERE   type = 'spark'
    AND     TO_CHAR(starttime,'yyyymmdd') >= '20190112'
    GROUP BY TO_CHAR(starttime,'yyyymmdd')
             ,projectid
             ,cu_usage
    ORDER BY mr_fee DESC
    ;

更多信息

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