1.stream1
监听端口9999
,stream2
监听端口9998
此时stream1和stream2 以及keyed水位线都是最小值
2.输入 a 1,最新的水位线为999ms(1000ms-1ms)
3.stream2
a = 5
stream2
stream2
package com.claroja;
import org.apache.flink.api.common.eventtime.SerializableTimestampAssigner;
import org.apache.flink.api.common.eventtime.WatermarkStrategy;
import org.apache.flink.api.common.typeinfo.TypeHint;
import org.apache.flink.api.java.tuple.Tuple2;
import org.apache.flink.streaming.api.TimeCharacteristic;
import org.apache.flink.streaming.api.datastream.SingleOutputStreamOperator;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
import org.apache.flink.streaming.api.functions.KeyedProcessFunction;
import org.apache.flink.util.Collector;
public class WatermarkKeyed {
public static void main(String[] args) throws Exception {
StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime);
env.setParallelism(1);
SingleOutputStreamOperator<Tuple2<String, Long>> stream1 = env
.socketTextStream("localhost", 9999,'\n')
.map(r -> Tuple2.of(r.split(" ")[0], Long.parseLong(r.split(" ")[1]) * 1000L))
.returns(new TypeHint<Tuple2<String, Long>>() {
})
.assignTimestampsAndWatermarks(
// 升序时间戳抽取
WatermarkStrategy.<Tuple2<String, Long>>forMonotonousTimestamps()
.withTimestampAssigner(new SerializableTimestampAssigner<Tuple2<String, Long>>() {
@Override
public long extractTimestamp(Tuple2<String, Long> stringLongTuple2, long l) {
return stringLongTuple2.f1;
}
})
);
SingleOutputStreamOperator<Tuple2<String, Long>> stream2 = env
.socketTextStream("localhost", 9998)
.map(r -> Tuple2.of(r.split(" ")[0], Long.parseLong(r.split(" ")[1]) * 1000L))
.returns(new TypeHint<Tuple2<String, Long>>() {
})
.assignTimestampsAndWatermarks(
// 升序时间戳抽取
WatermarkStrategy.<Tuple2<String, Long>>forMonotonousTimestamps()
.withTimestampAssigner(new SerializableTimestampAssigner<Tuple2<String, Long>>() {
@Override
public long extractTimestamp(Tuple2<String, Long> stringLongTuple2, long l) {
return stringLongTuple2.f1;
}
})
);
stream1
.union(stream2)
.keyBy(r -> r.f0)
.process(new Keyed())
.print();
env.execute();
}
public static class Keyed extends KeyedProcessFunction<String, Tuple2<String, Long>, String> {
//每收到一个数据就会掉用一次
@Override
public void processElement(Tuple2<String, Long> stringLongTuple2, Context context, Collector<String> collector) throws Exception {
collector.collect("当前水位线是:" + context.timerService().currentWatermark());
}
}
}