渐进式计算(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%。
Note-
由于范围查询场景首次使用渐进式计算时需要计算每天的中间结果,部分作业的运行时间会比普通模式还要长。建议先手动在渐进式计算模式下运行一次,避免在基线时段首次运行影响结果产出时间。
-
渐进式计算会存储每天的中间结果,占用额外存储空间;中间结果不再使用时会自动回收。额外空间开销成本和运行开销成本相比,总体上渐进式计算仍能节省费用并提高运行速度。
-
渐进式计算基础配置
首次开启渐进式计算时,建议先在开发环境测试,确认性能达到预期后再在生产环境启用。按如下步骤配置渐进式计算:
-
在提交作业时配置渐进式计算。
-
配置格式:
set odps.progressive.enable=[true|false]; -
参数说明:
-
true:表示使用渐进式计算方式处理提交的作业。
-
false:默认值为false。关闭渐进式计算方式。
-
-
-
配置渐进式计算模式:
-
配置格式:
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:输入数据为本年所有数据。适用于计算从当前年一月一日开始到当前的作业。
-
-
-
(可选)如果渐进式计算模式为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小时。
set odps.progressive.range.query.input.partition.pattern=PASS_BY_HOUR:1; -
配置更细粒度的时间列。
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操作,自动选择不同的存储方式。
Note建议您强制设置为cluster table存储方式。
-
-
-
设置作业并发运行实例数。
渐进式计算初次执行时需要刷新周期范围内的历史数据,会同时运行多个子任务。为避免资源被全部占用而影响其他作业运行,建议设置作业并发运行的最大实例数。
-
配置格式:
set odps.progressive.combine.exec.time.limit.num=<number>; -
参数说明:
number:默认值为15。作业并发运行的最大实例数>=1;
Note请您根据实际作业运行情况设置作业并发运行的最大实例数,实例数设置过大或者过小均会影响实际运行效率。
-
渐进式计算使用示例
-
第一天新建作业。
使用渐进式计算方式查询时间列范围为[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'; -
第二天(第二次)查询。
第一天执行作业脚本后,系统会根据每一个分区的数据进行计算,并将计算结果以天为单位保存到7个中间表中。在第二天查询时间列范围为[20200802,20200808]的数据时,首先会单独计算20200808列的数据,再和第一次运行生成7个中间表的数据整合起来得到最终结果。