背景:一般情况下, 窗口操作都有默认的窗口触发器,有时候默认的trigger不满足条件,就需要我们自己去定义相应的trigger 去决定处理窗口数据的时间。
触发器接口有五种方法,允许触发器对不同的事件作出反应
onElement()
添加到每个窗口的元素都会调用此方法。
onEventTime()
当注册的事件时间计时器触发时,将调用此方法。
onProcessingTime()
当注册的处理时间计时器触发时,将调用此方法。
onMerge()
与有状态触发器相关,并在两个触发器对应的窗口合并时合并它们的状态,例如在使用会话窗口时。(目前没使用过,了解不多)
clear()
执行删除相应窗口时所需的任何操作。(一般是删除定义的状态、定时器等)
这些trigger都是flink 提供的一些比较常用的触发器
onElement(),onEventTime(),onProcessingTime()
都要求返回一个TriggerResult
TriggerResult包含以下内容
/**
* @Description 自定义count触发器
* @auther eamon.yu
* @date 2020/11/23/023 15:29
*/
public class UserCountTrigger extends Trigger
上面触发器,和flink提供的CountTrigger有点不一样!!!
举个例子,如果数据满3条处理一次,
flink 的CountTrigger, 假设一个窗口内来了5条数据,前三天会当作满足条件进行处理,后面2条由于不满足3条不会进行处理,当到达窗口的关闭时间后,后面两条数据还是不会进行处理,数据就会丢失,下一个窗口又是重新开始, 对于我们的业务来说这样是不正确的
所以需要,当窗口关闭的时候,进行一次触发window的聚合函数,由于当前时间是基于processTime,可以在onProcessingTime 可以根据窗口关闭时间,手动去触发一次。
定义一个flink 程序进行消费数据,统计次数,当条数大于3 进行一次window的触发函数操作
/**
* @Description
* @auther eamon.yu
* @date 2020/11/23/023 11:22
*/
public class TestCountTrigger {
public static void main(String[] args) throws Exception {
final StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
env.setStreamTimeCharacteristic(TimeCharacteristic.ProcessingTime);
Properties propsConsumer = new Properties();
propsConsumer.setProperty("bootstrap.servers", "172.18.11.12:9092");
propsConsumer.setProperty("group.id", "trafficwisdom-streaming");
propsConsumer.put("enable.auto.commit", false);
propsConsumer.put("max.poll.records", 1000);
FlinkKafkaConsumer consumer = new FlinkKafkaConsumer("test_order1_ymz", new SimpleStringSchema(), propsConsumer);
consumer.setStartFromLatest();
DataStream stream = env.addSource(consumer);
stream.print();
DataStream> exposure = stream.map(new MapFunction>() {
@Override
public Tuple2 map(String value) throws Exception {
try {
String[] split = value.split(",");
return Tuple2.of(split[0],Integer.valueOf(split[1]) );
}catch (Exception e){
return null;
}
}
}).filter(Objects::nonNull);
DataStream> result = exposure.keyBy(0).
timeWindow(Time.minutes(1)).
trigger(UserCountTrigger.of(3)).sum(1);
result.print();
env.execute("test trigger");
}
}
往kafka中插入数据 a,1 五次,运行结果如下