1.编写代码
public class SavePointTest {
public static void main(String[] args) throws Exception {
//定义环境
StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
//设置并行度
env.setParallelism(1);
//数据源类型
DataStream<String> lines = env.socketTextStream("192.168.183.123", 9999);
SingleOutputStreamOperator<Tuple2<String, Integer>> wordAndOne = lines.map(new MapFunction<String, Tuple2<String, Integer>>() {
@Override
public Tuple2<String, Integer> map(String line) throws Exception {
if (line.startsWith("error")) {
throw new RuntimeException("输入的数据错误,抛出异常");
}
String[] fields = line.split(",");
return Tuple2.of(fields[0], 1);
}
});
KeyedStream<Tuple2<String, Integer>, String> tuple2StringKeyedStream = wordAndOne.keyBy(f -> f.f0);
SingleOutputStreamOperator<Tuple2<String, Integer>> count_value_state = tuple2StringKeyedStream.map(new RichMapFunction<Tuple2<String, Integer>, Tuple2<String, Integer>>() {
private ValueState<Integer> valueState;
//open方法中初始化或恢复状态
@Override
public void open(Configuration parameters) throws Exception {
//构建状态描述器
ValueStateDescriptor<Integer> stateDescriptor = new ValueStateDescriptor<Integer>("count_value_state", Types.INT);
//初始化或者恢复状态
valueState = getRuntimeContext().getState(stateDescriptor);
}
@Override
public Tuple2<String, Integer> map(Tuple2<String, Integer> value) throws Exception {
//获取状态中的历史值
Integer history = valueState.value();
Integer current = value.f1;
//如果状态中的历史值为null 说明这个key第一次进入分区
if (history == null) {
history = 0;
}
current += history;
//更新状态
valueState.update(current);
value.f1 = current;
return value;
}
});
count_value_state.print();
env.execute();
}
}
2.启动Socket 服务
nc -l 9999
3.启动flink程序
./flink run -c SavePointTest -d /home/ljj/Downloads/flinktest-1.0-SNAPSHOT.jar
4.输入内容
aa,a aa,a aa, aa,a ss,d ss,d dd,g
5.输出结果
(aa,1) (aa,2) (aa,3) (aa,4) (ss,1) (ss,2) (dd,1)
6.手都停止,并保存到相应的保存点
./flink stop -p /home/ljj/Downloads/savepoint d3267af83cc26d55e0bd66effdeefb93
7.从保存点启动服务
./flink run -s /home/ljj/Downloads/savepoint/savepoint-d3267a-3316b3295d12 -c SavePointTest -d /home/ljj/Downloads/flinktest-1.0-SNAPSHOT.jar
8.输入内容
aa,a ss,d dd,g
9.输出结果
(aa,5) (ss,3) (dd,2)
验证结果符合预期,重新启动后,输出的结果,是在停止之前的基础上累计的。