渐进式计算(Progressive Computing)是处于传统的流计算和批处理之间的一种计算方式,具有高资源利用率和低延迟的优势。本文为您介绍渐进式计算的基础配置、作业调优配置以及使用示例。

背景信息

渐进式计算能够处理增量数据并维护中间结果数据,提高了在计算资源消耗、执行时间调度、查询延迟、数据处理粒度等方面的灵活性。例如在范围查询(Range Query)场景下(即查询一段时间范围内的数据),使用传统批处理方式和渐进式计算方式每次统计过去一周的产品总销量,渐进式计算方式除首次执行外,其余每次执行的计算量减少了70%。如下所示:
  • 传统批处理方式:
    第n(n>=7)天执行需要处理[n-6,n]区间的数据;第n+1天执行需要处理[n-5,n+1]区间的数据。可以看出,第n+1天执行过程中有6天的数据是被重复计算的。如下图所示:重复数据图
  • 渐进式计算方式:
    第n(n>=7)天执行需要处理[n-6,n]区间的数据;第n+1天执行需要处理[n,n+1]区间的数据。即第n+1天执行只需要处理当天的增量数据,再和之前6天计算好的数据整合后得到过去一周的结果。第n+1天执行时的数据不会被重复计算,因此计算量减少了70%。
    说明
    • 由于范围查询场景在第一次使用渐进式计算时,需要计算出每一天的中间结果,因此部分作业的运行时间会比普通模式还要长,建议用户先手动在渐进式计算模式下运行一次,以免在基线时段第一次运行影响结果产出时间。
    • 由于渐进式计算会存储每天的中间结果,因此会占用额外的存储空间,中间结果会在不再会被使用的时候自动回收。额外空间开销成本和运行开销成本相比,总体上渐进式计算仍然会节省费用,运行速度更快。

渐进式计算基础配置

第一次开启渐进式计算时,建议先在开发环境进行测试,确保性能达到预期效果后再在生产环境启用。请您按如下步骤配置渐进式计算:
  1. 在提交作业时配置渐进式计算。
    • 配置格式:
      set odps.progressive.enable=[true|false];
    • 参数说明:
      • true:表示使用渐进式计算方式处理提交的作业。
      • false:默认值为false。关闭渐进式计算方式。
  2. 配置渐进式计算模式:
    • 配置格式:
      set odps.progressive.range.query.input.partition.pattern=<pattern_value>;
    • 参数说明:
      pattern_value的值以及含义如下:
      • PASS_BY_HOUR:输入数据为多个小时或分钟且非递增。适用于查询最近5分钟或最近3小时的数据。
      • PASS_BY_HOUR_AND_DAY:输入数据为多天,最近时间范围内的分区按小时分区存储。适用于查询最近3小时或最近3天的数据。
      • PASS_BY_DAY:输入数据为多天且非递增。适用于查询最近3天的数据。
      • INCREASING:输入数据为多天且递增,最近时间范围内的一个分区按天分区存储。适用于查询最近50天或最近3年的数据。
      • INCREASING_IN_A_MONTH:输入数据为本月所有数据。适用于计算从当前月一日开始到当前的作业。
      • INCREASING_IN_A_YEAR:输入数据为本年所有数据。适用于计算从当前年一月一日开始到当前的作业。
  3. (可选)如果渐进式计算模式为PASS_BY_HOUR时,您需根据实际作业周期长短,配置更细粒度时间列名。如果渐进式计算为其他模式,则不需要配置。
    • 配置格式
      • 格式一:
        set odps.progressive.range.query.time.partition.col.names=default:<col_name_day>:<col_name_hour>:<col_name_minute>|<col_name_day>:<col_name_hour>:<col_name_minute>|...;
      • 格式二:
        set odps.progressive.range.query.time.partition.col.names=<table_name>:<col_name_day>:<col_name_hour>:<col_name_minute>|<col_name_day>:<col_name_hour>:<col_name_minute>|...;
      • 格式三:
        set odps.progressive.range.query.time.partition.col.names=default:<col_name_day>:<col_name_hour>:<col_name_minute>,<table_name>:<col_name_day>:<col_name_hour>:<col_name_minute>,...;
    • 参数说明:
      • default:关键字。默认搜索符合条件的全部表。
      • table_name:指定查询对应时间列的表名。可以同时指定多张表,例如set odps.progressive.range.query.time.partition.col.names=table_1:day:hour,table_2:hour:minute;
      • <col_name_day>:<col_name_hour>:<col_name_minute>:指定查询对应表的时间列。可以同时指定多个列,例如set odps.progressive.range.query.time.partition.col.names=table_1:day:hour|day:hour2,table_2:day:hour:minute|day:hour2;
    • 配置示例:
      运行频率为1小时的作业,渐进式计算配置示例如下:
      1. 配置渐进式计算模式的基础单位为1小时。
        set odps.progressive.range.query.input.partition.pattern=PASS_BY_HOUR:1;
      2. 配置更细粒度的时间列
        set odps.progressive.range.query.time.partition.col.names=default:ds:hh|dt:hour;

渐进式计算调优配置

  • 强制设置中间表存储方式为cluster table。
    渐近式计算过程中如果生成中间表,在读取中间表数据后会将数据重新组合(shuffle)。如果将中间表存储方式设置为cluster table,计算性能会显著提高。
    • 配置格式:
      set range.query.force.cluster.table=[true|false];
    • 参数说明:
      • true:强制设置中间表存储方式为cluster table。
      • false:默认为false。系统会根据是否有shuffle操作,自动选择不同的存储方式。
        说明 建议您强制设置为cluster table存储方式。
  • 设置作业并发运行实例数。
    渐进式计算初次执行时需要刷新涉及渐进式计算周期范围内的历史数据,此时会同时运行很多子任务。为了避免资源被全部占用,导致其它作业不能正确运行,建议您设置作业并发运行的最大实例数。
    • 配置格式:
      set odps.progressive.combine.exec.time.limit.num=<number>;
    • 参数说明:
      number:默认值为15。作业并发运行的最大实例数>=1;
      说明 请您根据实际作业运行情况设置作业并发运行的最大实例数,实例数设置过大或者过小均会影响实际运行效率。

渐进式计算使用示例

  1. 第一天新建作业
    使用渐进式计算方式查询时间列范围为[20200801,20200807]的数据,并设置渐进式计算模式为天。作业脚本如下所示:
    set odps.progressive.enable=true;
    set odps.progressive.range.query.input.partition.pattern=PASS_BY_DAY;
    
    CREATE TABLE adl_aegis_webshell_test_neoke AS
    SELECT
    request_datetime,host,uri,src_ip,src_port,dst_ip,dst_port,method,post_data,user_agent,ret_code,cookie,
    referer,x_forward_for,rsp_content_type,rqs_content_type,content_length,jump_location,set_cookie,ttl,
    get_bigwebshell_uri(uri) AS nopar_uri,internet_ip
    FROM secbase.adl_aegis_webshell_newadd_beaverlog
    WHERE ds >= to_char(dateadd(to_date('20200807','yyyymmdd'),-6,'dd') ,'yyyymmdd')
    AND ds <= '20200807';
  2. 第二天(第二次)查询

    第一天执行作业脚本后,系统会根据每一个分区的数据进行计算,并将计算结果以天为单位保存到7个中间表中。在第二天查询时间列范围为[20200802,20200808]的数据时,首先会单独计算20200808列的数据,再和第一次运行生成7个中间表的数据整合起来得到最终结果。