flink异步流(async stream)解析

异步流都在 org.apache.flink.streaming.api.operators.async 包下面

AsyncResult

AsyncResult是存放在queue的中间结果,可以是watermark(AsyncCollectionResult),也可以是用户record(AsyncCollectionResult)。

方法有四个,分别是判断watermark、判断result、获取watermark、获取result

StreamElementQueueEntry是一个抽象类,实现了大部分逻辑,剩下主要业务逻辑是getFuture和onComplete。

它有两个实现类WatermarkQueueEntry和StreamRecordQueueEntry

watermark不是异步的,所以WatermarkQueueEntry中的future是_CompletableFuture.completedFuture(watermark);表示已经完成的future。_

StreamRecordQueueEntry 用户record是异步的。只有调用complete的时候才会赋值result,表示完成。赋值result在用户自定义异步函数中进行的。

AsyncWaitOperator

将进入的element包装成StreamRecordQueueEntry

处理的时候,首先会根据超时时间timeout,来注册定时器,超时的话会调用户自定义的timeout方法,按时完成会取消对应定时器。

添加到buffer中,这个buffer是有界的,可以控制异步的数量。

调用用户的asyncInvoke方法

addAsyncBufferEntry在添加的时候使用tryPut方法,没有空间的话就会wait。

queue中消息处理是在Emitter类中。

Emitter是在open方法中初始化的,放在emitterThread线程中单独处理。

Emitter的run方法中,取出一个element,这个element是异步已经完成的结果。调用output方法,将结果发送到下游。

output中针对watermark和element分别处理,watermark比较简单。主要看element。

首先是获取result,并发送到下游,再从队列中移除这个result,最后队列腾出一个空间,唤醒可能阻塞的主线程,主线程可以继续放入队列。

可以看到缓存队列StreamElementQueue是异步的关键,正常情况下是来一条数据处理一条数据,它是同步的,现在使用StreamElementQueue将消息先缓存起来,从StreamElementQueue中出去的消息都是已经经过处理的,消息处理耗时整体缩短。

举例现在有10条消息,每条消息处理时间是1s,那么不使用异步,同步处理,处理总时间就是10s。使用异步流的话,就是10条消息会先进入StreamElementQueue中,在StreamElementQueue中同时已经处理,最快处理总时间达到1s。

StreamElementQueue

主要是三个方法,

tryPut添加element,没空间就是false,添加成功就是true

peekBlockingly、poll 两个方法都是获取第一个完成element,区别是是否移除。

它有两个实现类OrderedStreamElementQueue和UnorderedStreamElementQueue,对应有序和无序。

顺序是指的队列弹出element顺序是不是element放入的顺序,即在获取第一个完成的element是不是第一个放入的element。

OrderedStreamElementQueue

比较简单。

capacity是容量大小,queue是实际存放的队列。

tryPut,空间有剩余调用addEntry放入元素。addEntry将元素放入尾部,并注册onCompleteHandler,通知headIsCompleted。

peekBlockingly和poll类似。

在poll中,首先队列是空的或者队列头部没有完成,headIsCompleted阻塞。headIsCompleted在头部完成的时候会回调onCompleteHandler释放。队列poll移除头部。

UnorderedStreamElementQueue

无序,这个效率更高。但是这个无序并不是完全无序,是在watermark之间无序。

  • uncompletedQueue中存放是按照watermark划分成的几个批次的没有完成的element
  • completedQueue是已经完成的单个element
  • firstSet是存放时间最久批次的element
  • lastSet是当前进入的element需要存放的批次

基本思路是新的element进入后放到lastSet中,如果是watermark进入的话就新开一个批次。获取第一个完成的element的时候从firstSet中获取。

tryPut还是调用addEntry方法。如果是element,就直接加入lastSet中。是watermark就要新开批次,创建新的lastSet,将新的空的lastSet加入到uncompletedQueue。要是firstSet为空,表示没有未完成的element,将watermark加入firstSet中,firstSet不为空,有没完成的element,这个watermark插入uncompletedQueue中起隔断作用。最后注册回调函数onCompleteHandler,在element完成的时候触发。

onCompleteHandler是在element完成的时候触发。每个element的耗时都是随机的。这里首先要求firstSet中都完成,再处理下一批次。完成的element放入到completedQueue中。

peekBlockingly和poll比较简单,从completedQueue中直接获取即可。

AsyncFunction

最后就是api的使用了。org.apache.flink.streaming.api.functions.async.AsyncFunction

流程总结

相关推荐
牛企老板俱乐部1 小时前
广东机器人结构验证手板产业格局:深圳珠海东莞三城分析
大数据·人工智能
Keystone_Onion1 小时前
基于5大仓群路由算法的中大件美国海外仓降本架构与数据实测分析
大数据
buligbulig1 小时前
智能电网的数据底座:电力行业大数据治理路径解析
大数据
ltqvibe1 小时前
企业AI改造的四层路径:从点上应用到企业大脑
大数据·人工智能·本体语义平台·企业ai改造·数据打通·企业大脑·企业认知基础设施
anxiao_m1 小时前
园区数字孪生怎么搭建?主流方案与服务商深度对比
大数据·运维·人工智能
stonewl25992 小时前
2026化工企业标签打印自动化方案
大数据
独隅3 小时前
VS Code Git 工作树多分支并行开发实战指南
大数据·git·elasticsearch
千维百策6663 小时前
AI 软件开发中的人与智能体:软件工程循环、人在环路中与框架工程
大数据·人工智能·软件工程
梦伢mm4 小时前
直播切片素材不足,易元 AI 可以自动拆分直播视频做带货素材吗?
大数据
Lalolander5 小时前
2026年成长型企业上金蝶,抓3个重点(预算有限如何起步)
大数据·制造·erp·金蝶erp·erp实施·金蝶ai星空