1. 타이머 소개
Timer (Timer)는 처리 시간 / 이벤트 시간 변경을 감지하고 활용하기 위해 Flink Streaming API에서 제공하는 메커니즘입니다.
Timer를 사용하는 가장 일반적인 위치는 KeyedProcessFunction입니다. processElement () 메서드에 Timer를 등록한 다음 Timer가 트리거 될 때 콜백 논리로 onTimer () 메서드를 재정의합니다. 다른 시간 특성에 따라 :
(1) 처리 시간 -Context.timerService (). registerProcessingTimeTimer ()를 호출하여 등록합니다 .onTimer ()는 시스템 타임 스탬프가 Timer에서 설정 한 타임 스탬프에 도달하면 트리거됩니다.
(2) 이벤트 시간 -Context.timerService (). registerEventTimeTimer ()를 호출하여 등록합니다 .onTimer ()는 Flink의 내부 워터 마크가 Timer가 설정 한 타임 스탬프에 도달하거나 초과 할 때 트리거됩니다.
둘째, 데모 사용
데모 기능은 wordCount 및 Timer에 대해 mapState를 사용하여 2 초마다 주기적으로 상태를 지우는 것입니다.
(1) 프로그램 항목
package testOntimer;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
/**
* @程序功能:读取文件,进行wordCount,利用state测试onTimer定时器
* @author gaoj
* @Created_in 2020-12-08
*/
public class Driver {
public static void main(String[] args) throws Exception {
StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
env
.addSource(new Source())
.flatMap(new Map())
.keyBy(t -> t._1)
.process(new Process())
.print();
env.execute();
}
}
(2) 프로그램 데이터 소스
package testOntimer;
import org.apache.commons.lang3.StringUtils;
import org.apache.flink.streaming.api.functions.source.RichSourceFunction;
import java.io.BufferedReader;
import java.io.FileReader;
import java.util.concurrent.TimeUnit;
public class Source extends RichSourceFunction<String> {
private Boolean isRunning = true;
@Override
public void run(SourceContext<String> ctx) throws Exception {
BufferedReader bufferedReader = new BufferedReader(new FileReader("D:\\test.txt"));
while (isRunning){
String line = bufferedReader.readLine();
if(StringUtils.isNotBlank(line)){
ctx.collect(line);
}
TimeUnit.SECONDS.sleep(10);
}
}
@Override
public void cancel() {
isRunning = false;
}
}
(3) 데이터 소스 변환
package testOntimer;
import org.apache.flink.api.common.functions.RichFlatMapFunction;
import org.apache.flink.util.Collector;
import scala.Tuple2;
public class Map extends RichFlatMapFunction<String, Tuple2<String,Integer>> {
@Override
public void flatMap(String value, Collector<Tuple2<String, Integer>> out) throws Exception {
String[] split = value.split(",");
for (String s : split) {
out.collect(new Tuple2<>(s,1));
}
}
}
(4) wordCount 수행
package testOntimer;
import org.apache.flink.api.common.state.MapState;
import org.apache.flink.api.common.state.MapStateDescriptor;
import org.apache.flink.api.common.state.ValueState;
import org.apache.flink.api.common.state.ValueStateDescriptor;
import org.apache.flink.api.common.typeinfo.TypeHint;
import org.apache.flink.api.common.typeinfo.TypeInformation;
import org.apache.flink.configuration.Configuration;
import org.apache.flink.streaming.api.functions.KeyedProcessFunction;
import org.apache.flink.util.Collector;
import scala.Tuple2;
import java.util.Calendar;
public class Process extends KeyedProcessFunction<String, Tuple2<String,Integer> ,Tuple2<String,Integer>> {
private transient MapState<String,Integer> mapState;
private transient ValueState<Integer> valueState;
@Override
public void open(Configuration parameters) throws Exception {
super.open(parameters);
MapStateDescriptor<String,Integer> mapStateDescriptor = new MapStateDescriptor<>("valueStateDesc",
TypeInformation.of(new TypeHint<String>() {}),
TypeInformation.of(new TypeHint<Integer>() {}));
mapState = getRuntimeContext().getMapState(mapStateDescriptor);
ValueStateDescriptor<Integer> ValueStateDescriptor = new ValueStateDescriptor<>("phoneCount",
TypeInformation.of(new TypeHint<Integer>() {
}));
valueState=getRuntimeContext().getState(ValueStateDescriptor );
}
@Override
public void processElement(Tuple2<String,Integer> value, Context ctx, Collector<Tuple2<String, Integer>> out) throws Exception {
if (valueState.value()==null){
ctx.timerService().registerProcessingTimeTimer(System.currentTimeMillis()+2000);
}
int i = mapState.contains(value._1) ? mapState.get(value._1) : 0;
int i1 = i + 1;
mapState.put(value._1,i1);
out.collect(new Tuple2<>(value._1,i1));
}
@Override
public void onTimer(long timestamp, OnTimerContext ctx, Collector<Tuple2<String, Integer>> out) throws Exception {
mapState.clear();
valueState.clear();
}
@Override
public void close() throws Exception {
super.close();
}
}