关于Flink窗口计算的触发器(Trigger)

本文深入探讨了Flink中的触发器机制,详细解释了Trigger如何决定窗口何时准备就绪并进行计算,包括其五种核心方法及TriggerResult枚举的作用。并通过自定义计数触发器的实例,展示了如何在实际应用中使用这些概念。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Trigger决定了什么时候窗⼝准备就绪了,⼀旦窗⼝准备就绪就可以使⽤WindowFunction进⾏计算。每⼀个 WindowAssigner 都会有⼀个默认的Trigger。如果默认的Trigger不满⾜⽤户的需求⽤户可以⾃定义Trigger。

在这里插入图片描述
触发器接⼝具有五种⽅法,这些⽅法允许触发器对不同事件做出反应:

public abstract class Trigger<T, W extends Window> implements Serializable {
/**
 只要有元素落⼊到当前窗⼝, 就会调⽤该⽅法
 * @param element 收到的元素
 * @param timestamp 元素抵达时间.
 * @param window 元素所属的window窗⼝.
 * @param ctx ⼀个上下⽂对象,通常⽤该对象注册 timer(ProcessingTime/EventTime) 回调.
 */
 public abstract TriggerResult onElement(T element, long timestamp, W window,
TriggerContext ctx) throws Exception;
 /**
 * processing-time 定时器回调函数
 *
 * @param time 定时器触发的时间.
 * @param window 定时器触发的窗⼝对象.
 * @param ctx ⼀个上下⽂对象,通常⽤该对象注册 timer(ProcessingTime/EventTime) 回调.
 */
 public abstract TriggerResult onProcessingTime(long time, W window, TriggerContext
ctx) throws Exception;

 /**
 * event-time 定时器回调函数
 *
 * @param time 定时器触发的时间.
 * @param window 定时器触发的窗⼝对象.
 * @param ctx ⼀个上下⽂对象,通常⽤该对象注册 timer(ProcessingTime/EventTime) 回调.
 */
 public abstract TriggerResult onEventTime(long time, W window, TriggerContext ctx)
throws Exception;

 /**
 * 当 多个窗⼝合并到⼀个窗⼝的时候,调⽤该⽅法,例如系统SessionWindow
 * {@link org.apache.flink.streaming.api.windowing.assigners.WindowAssigner}.
 *
 * @param window 合并后的新窗⼝对象
 * @param ctx ⼀个上下⽂对象,通常⽤该对象注册 timer(ProcessingTime/EventTime)回调以及访问
状态
 */
 public void onMerge(W window, OnMergeContext ctx) throws Exception {
 throw new UnsupportedOperationException("This trigger does not support merging.");
 }
 /**
 * 当窗⼝被删除后执⾏所需的任何操作。例如:可以清除定时器或者删除状态数据
 */
 public abstract void clear(W window, TriggerContext ctx) throws Exception;
}

关于上述⽅法,需要注意两件事:
1)前三个⽅法决定如何通过返回TriggerResult来决定窗⼝是否就绪。

public enum TriggerResult {
 /**
 * 不触发,也不删除元素
 */
 CONTINUE(false, false),
 /**
 * 触发窗⼝,窗⼝出发后删除窗⼝中的元素
 */
 FIRE_AND_PURGE(true, true),
 /**
 * 触发窗⼝,但是保留窗⼝元素
 */
 FIRE(true, false),
 /**
 * 不触发窗⼝,丢弃窗⼝,并且删除窗⼝的元素
 */
 PURGE(false, true);
 private final boolean fire;//是否触发窗⼝
 private final boolean purge;//是否清除窗⼝元素
 ...
 }

2)这些⽅法中的任何⼀种都可以⽤于注册处理或事件时间计时器以⽤于将来的操作.

案例使⽤
class UserDefineCountTrigger(maxCount:Long) extends Trigger[String,TimeWindow]{
 var rsd:ReducingStateDescriptor[Long]= new ReducingStateDescriptor[Long]("rsd",new
ReduceFunction[Long] {
 override def reduce(value1: Long, value2: Long): Long = value1+value2
 },createTypeInformation[Long])
 override def onElement(element: String, timestamp: Long, window: TimeWindow, ctx:
Trigger.TriggerContext): TriggerResult = {
 val state: ReducingState[Long] = ctx.getPartitionedState(rsd)
 state.add(1L)
 if(state.get() >= maxCount){
 state.clear()
 return TriggerResult.FIRE_AND_PURGE
 }else{
 return TriggerResult.CONTINUE
 }
 }
 override def onProcessingTime(time: Long, window: TimeWindow, ctx:
Trigger.TriggerContext): TriggerResult = TriggerResult.CONTINUE
 override def onEventTime(time: Long, window: TimeWindow, ctx:
Trigger.TriggerContext): TriggerResult =TriggerResult.CONTINUE
 override def clear(window: TimeWindow, ctx: Trigger.TriggerContext): Unit = {
 println("==clear==")
 ctx.getPartitionedState(rsd).clear()
 }
}
object FlinkTumblingWindowWithCountTrigger {
 def main(args: Array[String]): Unit = {
 val env = StreamExecutionEnvironment.getExecutionEnvironment
 val text = env.socketTextStream("CentOS", 9999)
 //3.执⾏DataStream的转换算⼦
 val counts = text.flatMap(line=>line.split("\\s+"))
 .windowAll(TumblingProcessingTimeWindows.of(Time.seconds(5)))
 .trigger(new UserDefineCountTrigger(4L))
 .apply(new UserDefineGlobalWindowFunction)
 .print()
 //5.执⾏流计算任务
 env.execute("Global Window Stream WordCount")
 }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值