【阿里内部应用】利用blink CEP实现流计算中的超时统计问题

本文涉及的产品
实时计算 Flink 版,5000CU*H 3个月
简介: 案例与解决方案汇总页:阿里云实时计算产品案例&解决方案汇总一. 背景介绍如<利用blink+MQ实现流计算中的延时统计问题>一文中所描述的场景,我们将其简化为以下案例:实时流的数据源结构如下:物流订单号支付时间仓接单时间仓出库时间LP12018-08-01 08:00 ...

案例与解决方案汇总页:
阿里云实时计算产品案例&解决方案汇总

一. 背景介绍

如<利用blink+MQ实现流计算中的延时统计问题>一文中所描述的场景,我们将其简化为以下案例:
实时流的数据源结构如下:

物流订单号 支付时间 仓接单时间 仓出库时间
LP1 2018-08-01 08:00
LP1 2018-08-01 08:00 2018-08-01 09:00
LP2 2018-08-01 09:10
LP2 2018-08-01 09:10 2018-08-01 09:50
LP2 2018-08-01 09:10 2018-08-01 09:50 ​2018-08-01 12:00

我们期望通过以上数据源,按照支付日期统计,每个仓库的仓接单量、仓出库量、仓接单超2H未出库单量、仓接单超6H未出库单量。可以看出,其中LP1仓接单时间是2018-08-01 09:00,但一直到2018-08-01 12:00点之前,一直都没有出库,LP1满足仓接单超2H未出库的行为。

该场景的难点就在于:订单未出库。而对于TT中的源消息流,订单未出库,TT就不会下发新的消息,不下发新的消息,blink就无法被触发计算。而针对上述的场景,对于LP1,我们需要在仓接单时间是2018-08-01 09:00+2H,也就是2018-08-01 11:00的之后,就要知道LP1已经仓接单但超2H未出库了。

二. 解决方案

本文主要是利用blink CEP来实现上述场景,具体实现步骤如下所述。
第一步:在source DDL中定义event_timestamp,并定义sink,如下:

----定义source
create table sourcett_dwd_ri
(
     lg_order_code                  varchar comment '物流订单号'
    ,ded_pay_time                   varchar comment '支付时间'
    ,store_code                     varchar comment '仓库编码'
    ,store_name                     varchar comment '仓库名称'
    ,wms_create_time                varchar comment '仓接单时间'
    ,wms_consign_create_time        varchar comment '仓出库时间'
    ,evtstamp as case when coalesce(wms_create_time, '') <> ''
                      then to_timestamp(wms_create_time, 'yyyy-MM-dd HH:mm:ss')
                      else to_timestamp('1970-01-01 00:00:00', 'yyyy-MM-dd HH:mm:ss')
                 end   --构造event_timestamp,如果源表本身带有消息的occur_time,可直接选择occur_time作为event_timestamp
    ,WATERMARK FOR evtstamp AS withOffset(evtstamp, 10000)  --设置延迟10秒处理
)
with
(
     type='tt'
    ,topic='dwd_ri'
    ,accessKey='xxxxxx'
    ,accessId='xxxxxx'
    ,lengthCheck='PAD'
    ,nullValues='\\N|'
);


----定义sink
create table sink_hybrid_blink_cep
(
     ded_pay_date                   varchar comment '支付日期'
    ,store_code                     varchar comment '仓库编码'
    ,store_name                     varchar comment '仓库名称'
    ,wms_create_ord_cnt             bigint  comment '仓接单量'
    ,wms_confirm_ord_cnt            bigint  comment '仓出库量'
    ,wmsin_nowmsout_2h_ord_cnt      bigint  comment '仓接单超2小时未出库单量'
    ,wmsin_nowmsout_6h_ord_cnt      bigint  comment '仓接单超6小时未出库单量'    
    ,sub_partition                  bigint  comment '二级分区(支付日期)'
    ,PRIMARY KEY (ded_pay_date, store_code, sub_partition)
)
with
(
     type='PetaData'
    ,url = 'xxxxxx'
    ,tableName='blink_cep'
    ,userName='xxxxxx'
    ,password='xxxxxx'
    ,bufferSize='30000'
    ,batchSize='3000'
    ,batchWriteTimeoutMs='15000'
);
AI 代码解读

第二步:根据blink CEP的标准语义进行改写,如下:

create view blink_cep_v1
as
select   '仓接单-仓出库超时' as timeout_type
        ,lg_order_code
        ,wms_create_time as start_time
        ,wms_consign_create_time as end_time
from     source_dwd_csn_whc_lgt_fl_ord_ri
MATCH_RECOGNIZE
(
         PARTITION BY lg_order_code
         ORDER BY     evtstamp
         MEASURES
                      e1.wms_create_time         as wms_create_time
                     ,e2.wms_consign_create_time as wms_consign_create_time
         ONE ROW PER MATCH WITH TIMEOUT ROWS  --重要,必须设置延迟也下发
         AFTER MATCH SKIP TO NEXT ROW
         PATTERN (e1 -> e2) WITHIN INTERVAL '6' HOUR
         EMIT TIMEOUT (INTERVAL '2' HOUR, INTERVAL '6' HOUR)
         DEFINE
             e1 as e1.wms_create_time is not null and e1.wms_consign_create_time is null
            ,e2 as e2.wms_create_time is not null and e2.wms_consign_create_time is not null
)
where    wms_create_time is not null      --重要,可以大大减少进入CEP的消息量
and      wms_consign_create_time is null  --重要,可以大大减少进入CEP的消息量
;
AI 代码解读

第三步:根据blink的执行机制,我们通过源实时流sourcett_dwd_ri与超时消息流blink_cep_v1关联,来触发blink对超时消息进行聚合操作,如下:

create view blink_cep_v2
as
select   a.lg_order_code                       as lg_order_code
        ,last_value(a.store_code             ) as store_code
        ,last_value(a.store_name             ) as store_name
        ,last_value(a.ded_pay_time           ) as ded_pay_time
        ,last_value(a.wms_create_time        ) as wms_create_time
        ,last_value(a.real_wms_confirm_time  ) as real_wms_confirm_time
        ,last_value(case when coalesce(a.wms_create_time, '') <> ''
                         and  coalesce(a.real_wms_confirm_time, '') = '' 
                         and  now() - unix_timestamp(a.wms_create_time,'yyyy-MM-dd HH:mm:ss') >= 7200
                         then 'Y' else 'N' end) as flag_01
        ,last_value(case when coalesce(a.wms_create_time, '') <> ''
                         and  coalesce(a.real_wms_confirm_time, '') = '' 
                         and  now() - unix_timestamp(a.wms_create_time,'yyyy-MM-dd HH:mm:ss') >= 21600
                         then 'Y' else 'N' end) as flag_02
from
        (select   lg_order_code                       as lg_order_code
                 ,last_value(store_code             ) as store_code
                 ,last_value(store_name             ) as store_name
                 ,last_value(ded_pay_time           ) as ded_pay_time
                 ,last_value(wms_create_time        ) as wms_create_time
                 ,last_value(wms_consign_create_time) as real_wms_confirm_time
         from     sourcett_dwd_ri
         group by lg_order_code
         ) a
left outer join
        (select   lg_order_code
                 ,count(*) as cnt
         from     blink_cep_v1
         group by lg_order_code
         ) b
on       a.lg_order_code = b.lg_order_code
group by a.lg_order_code
;


insert into sink_hybrid_blink_cep
select   regexp_replace(substring(a.ded_pay_time, 1, 10), '-', '') as ded_pay_date
        ,a.store_code
        ,max(a.store_name)        as store_name
        ,count(case when coalesce(a.wms_create_time, '') <> '' then a.lg_order_code end) as wmsin_ord_cnt
        ,count(case when coalesce(a.real_wms_confirm_time, '') <> '' then a.lg_order_code end) as wmsout_ord_cnt
        ,count(case when a.flag_01 = 'Y' then a.lg_order_code end) as wmsin_nowmsout_2h_ord_cnt
        ,count(case when a.flag_02 = 'Y' then a.lg_order_code end) as wmsin_nowmsout_6h_ord_cnt
        ,cast(regexp_replace(SUBSTRING(ded_pay_time, 1, 10), '-', '') as bigint) as sub_partition
from     blink_cep_v2 as t1
where    coalesce(lg_cancel_time, '') = ''
and      coalesce(ded_pay_time, '') <> ''
group by regexp_replace(substring(ded_pay_time, 1, 10), '-', '')
        ,a.store_code
;
AI 代码解读

三. 问题拓展

  1. blink CEP的参数比较多,要完全看懂,着实需要一些时间,但CEP的强大是毋庸置疑的。CEP不仅可以解决物流场景中的超时统计问题,风控中的很多场景也是信手拈来。这里有一个风控中的场景,通过上述物流案例的用法,我们是否能推敲出这个场景的用法呢?
    风控案例测试数据如下:
刷卡时间 银行卡ID 刷卡地点
2018-04-13 12:00:00 1 WW
2018-04-13 12:05:00 1 WW1
2018-04-13 12:10:00 1 WW2
2018-04-13 12:20:00 1 WW

我们认为,当一张银行卡在10min之内,在不同的地点被刷卡大于等于两次,我们就期望对消费者出发预警机制。

  1. blink CEP是万能的么?答案是否定的,当消息乱序程度比较高的时候,实时性和准确性就成了一对矛盾的存在。要想实时性比较高,必然要求设置的offset越小越好,但offset设置比较小,就直接可能导致很多eventtime<watermark-offset的消息,直接被丢弃,准确性很难保证。比如,在CP回传物流详情的时候,经常回传的时间跟实操的时间差异很大(实操时间是10点,但回传时间是15点),如果以实操时间作为eventtime,可能就会导致这种差异很大的消息被直接丢掉,无法进入CEP,进而无法触发CEP后续的计算,在使用CEP的过程中,应该注意这一点。

四. 作者简介

花名:缘桥,来自菜鸟-CTO-数据部-仓配数据研发,主要负责菜鸟仓配业务的离线和实时数据仓库建设以及创新数据技术和工具的探索和应用。

image

相关实践学习
基于Hologres轻松玩转一站式实时仓库
本场景介绍如何利用阿里云MaxCompute、实时计算Flink和交互式分析服务Hologres开发离线、实时数据融合分析的数据大屏应用。
Linux入门到精通
本套课程是从入门开始的Linux学习课程,适合初学者阅读。由浅入深案例丰富,通俗易懂。主要涉及基础的系统操作以及工作中常用的各种服务软件的应用、部署和优化。即使是零基础的学员,只要能够坚持把所有章节都学完,也一定会受益匪浅。
付空
+关注
目录
打赏
0
1
1
0
28424
分享
相关文章
snprintf的用法
简要介绍了snprintf的常用方法,能大大的简化我们的代码
实时计算 Flink版产品使用问题之该如何解决checkpoint频繁失败
实时计算Flink版作为一种强大的流处理和批处理统一的计算框架,广泛应用于各种需要实时数据处理和分析的场景。实时计算Flink版通常结合SQL接口、DataStream API、以及与上下游数据源和存储系统的丰富连接器,提供了一套全面的解决方案,以应对各种实时计算需求。其低延迟、高吞吐、容错性强的特点,使其成为众多企业和组织实时数据处理首选的技术平台。以下是实时计算Flink版的一些典型使用合集。
抖音集团电商流量实时数仓建设实践
本文基于抖音集团电商数据工程师姚遥在Flink Forward Asia 2024的分享,围绕电商流量数据处理展开。内容涵盖业务挑战、电商流量建模架构、流批一体实践、大流量任务调优及总结展望五个部分。通过数据建模与优化,实现效率、质量、成本和稳定性全面提升,数据质量达99%以上,任务性能提升70%。未来将聚焦自动化、低代码化与成本优化,探索更高效的流批一体化方案。
251 12
抖音集团电商流量实时数仓建设实践
MNN:阿里开源的轻量级深度学习推理框架,支持在移动端等多种终端上运行,兼容主流的模型格式
MNN 是阿里巴巴开源的轻量级深度学习推理框架,支持多种设备和主流模型格式,具备高性能和易用性,适用于移动端、服务器和嵌入式设备。
1499 18
MNN:阿里开源的轻量级深度学习推理框架,支持在移动端等多种终端上运行,兼容主流的模型格式
好消息,在 Visual Studio 中可以免费使用 GitHub Copilot 了!
好消息,在 Visual Studio 中可以免费使用 GitHub Copilot 了!
514 11
Flink Forward Asia 2024 即将盛大开幕!
Flink Forward Asia 2024是由Apache官方授权的技术大会,聚焦流式湖仓、流批一体、AI大模型等热点方向,旨在分享Flink社区最新动态及实践经验,是Flink开发者和使用者不容错过的盛会。大会不仅探讨了Flink在实时大数据分析中的应用,还深入讨论了Data+AI领域的新成果,如基于Flink和Elasticsearch的企业级高级RAG架构设计,展示了Flink在多模态数据处理、实时数据向量化等方面的强大能力。
spring源码设计模式分析(八)-访问者模式
spring源码设计模式分析(八)-访问者模式
实时计算 Flink版操作报错合集之perjob提交给yarn,报错显示无法连接yarn- Connecting to ResourceManager,是什么导致的
在使用实时计算Flink版过程中,可能会遇到各种错误,了解这些错误的原因及解决方法对于高效排错至关重要。针对具体问题,查看Flink的日志是关键,它们通常会提供更详细的错误信息和堆栈跟踪,有助于定位问题。此外,Flink社区文档和官方论坛也是寻求帮助的好去处。以下是一些常见的操作报错及其可能的原因与解决策略。
|
10月前
ARM64技术 —— MMU处于关闭状态时,内存访问是怎样的?
ARM64技术 —— MMU处于关闭状态时,内存访问是怎样的?
Redis:高性能、多功能的内存数据库
Redis是一种开源、高性能的内存数据库,广泛应用于缓存、会话存储、实时数据处理等场景。本文将介绍Redis的特点、优势和主要功能,探讨它在不同应用领域中的应用场景,以及如何充分利用Redis提升应用性能和可靠性。无论是小型应用还是大规模的分布式系统,Redis都是一个值得关注的强大工具。
223 0
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等

登录插画

登录以查看您的控制台资源

管理云资源
状态一览
快捷访问