前面几篇博客当中,我们介绍的主要是checkpoint,本篇博客我们介绍一个很相似的机制:SavePoint.
SavePoint概念介绍
Flink通过Savepoint功能可以做到程序升级后,继续从升级前的那个点开始执行计算,保证数据不中断,SavePoint可以生成全局、一致性的快照,也可以保存数据源、offset,
operator操作状态等信息,还可以从应用在过去任意做了savepoint的时刻开始继续消费。
CheckPoint和SavePoint的区别
1. checkPoint
应用定时触发,用于保存状态,会过期,内部应用失败重启的时候使用;
2、savePoint
用户手动执行,是指向Checkpoint的指针,不会过期在升级的情况下使用;
SavePoint的配置方式
1、在flink-conf.yaml中配置Savepoint存储位置
该步骤不是必须设置,但是设置后,后面创建指定Job的Savepoint时,可以不用在手动执行命令时指定Savepoint的位置。
state.savepoints.dir: hdfs://namenode:9000/flink/savepoints
2、触发一个savepoint【直接触发或者在cancel的时候触发】
bin/flink savepoint jobId [targetDirectory] [-yid yarnAppId]【针对on yarn模式需要指定-yid参数】
bin/flink cancel -s [targetDirectory] jobId [-yid yarnAppId]【针对on yarn模式需要指定-yid参数】
3、从指定的savepoint启动job
bin/flink run -s savepointPath [runArgs]
SavePoint案例实战
上面介绍了这么多,实际演练一下:
示例程序:
package Stream_example; import org.apache.flink.api.common.functions.FlatMapFunction; import org.apache.flink.api.common.restartstrategy.RestartStrategies; import org.apache.flink.api.java.tuple.Tuple2; import org.apache.flink.runtime.state.filesystem.FsStateBackend; import org.apache.flink.streaming.api.CheckpointingMode; import org.apache.flink.streaming.api.datastream.DataStream; import org.apache.flink.streaming.api.datastream.DataStreamSource; import org.apache.flink.streaming.api.environment.CheckpointConfig; import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment; import org.apache.flink.streaming.api.windowing.time.Time; import org.apache.flink.util.Collector; import java.util.concurrent.TimeUnit; /** * @ClassName SocketWindowWordCountJavaCheckPoint * {功能描述:Flink当中的checkpoint机制 * 滑动窗口计算:实现每隔2秒对最近1个小时的数据进行汇总计算} * @Author Admin * CREATE 2020/10/5 18:39 * @Version 1.0.0 */ public class SocketWindowWordCountJavaCheckPoint { public static void main(String[] args) throws Exception { //获取Flink的运行环境. StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment(); //开启flink的checkpoint功能:每隔1000 ms启动一个检查点(设置checkpoint的生命周期.) env.enableCheckpointing(1000); //checkpoint高级选项设置. //设置checkpoint的模式为exactly-once(这也是默认值) env.getCheckpointConfig().setCheckpointingMode(CheckpointingMode.EXACTLY_ONCE); //确保检查点之间至少有500ms的间隔(即checkpoint的最小间隔) env.getCheckpointConfig().setMinPauseBetweenCheckpoints(500); //检查点必须在1min之内完成,否则会被丢弃(checkpoint的超时时间) env.getCheckpointConfig().setCheckpointTimeout(60000); //同一时间只允许操作一个检查点 env.getCheckpointConfig().setMaxConcurrentCheckpoints(1); //Flink程序即使被cancel后,也会保留checkpoint数据,以便根据实际需要恢复到指定的checkpoint. env.getCheckpointConfig().enableExternalizedCheckpoints(CheckpointConfig.ExternalizedCheckpointCleanup.RETAIN_ON_CANCELLATION); //设置statebackend,指定state和checkpoint的数据存储位置(checkpoint的数据必须得有一个可以持久化存储的地方) env.setStateBackend(new FsStateBackend("hdfs://s101:9000/flink/checkpoints")); //重启策略采用固定间隔 (Fixed delay) :任务发生故障时重启3次,每次间隔是10秒. env.setRestartStrategy(RestartStrategies.fixedDelayRestart(3,10000)); //连接Socket获取输入的数据. DataStreamSource<String> socketTextStream = env.socketTextStream("192.168.140.103", 8888, " "); DataStream<Tuple2<String, Integer>> tuple2SingleOutputStreamOperator = socketTextStream.flatMap(new FlatMapFunction<String, Tuple2<String, Integer>>() { /** * @param value socket传过来的一行一行的数据. * @param out * @throws Exception */ @Override public void flatMap(String line, Collector<Tuple2<String, Integer>> out) throws Exception { String[] splited = line.split("\W+"); for (String word : splited) { out.collect(new Tuple2<>(word, 1)); } } }); //指定时间窗口大小为1*60*60s,指定时间间隔为2s. DataStream<Tuple2<String, Integer>> sumData = tuple2SingleOutputStreamOperator.keyBy(0).timeWindow(Time.seconds(3600), Time.seconds(2)).sum(1); sumData.print(); env.execute("SocketWindowWordCountJavaCheckPoint"); } }
从上面的程序当中,你可能会问:这里也看不到savepoint代码的影子啊?是的,因为savepoint是需要手动操作的!
当我们启动完程序后,我们在页面上面是看到SavePoint的数据是null:
然后我们手动触发一次SavePoint:
[root@s101 /usr/local/software]#flink savepoint 547ac058d6a84efa538be6db25a9224a hdfs://s101:9000/flink/savepoints -yid application_1601832819602_0001 2020-10-05 13:25:43,700 INFO org.apache.flink.yarn.cli.FlinkYarnSessionCli - Found Yarn properties file under /tmp/.yarn-properties-root. 2020-10-05 13:25:43,700 INFO org.apache.flink.yarn.cli.FlinkYarnSessionCli - Found Yarn properties file under /tmp/.yarn-properties-root. 2020-10-05 13:25:44,471 INFO org.apache.hadoop.yarn.client.RMProxy - Connecting to ResourceManager at s101/192.168.140.101:8032 2020-10-05 13:25:44,692 INFO org.apache.flink.yarn.cli.FlinkYarnSessionCli - No path for the flink jar passed. Using the location of class org.apache.flink.yarn.YarnClusterDescriptor to locate the jar 2020-10-05 13:25:44,692 INFO org.apache.flink.yarn.cli.FlinkYarnSessionCli - No path for the flink jar passed. Using the location of class org.apache.flink.yarn.YarnClusterDescriptor to locate the jar 2020-10-05 13:25:44,711 WARN org.apache.flink.yarn.AbstractYarnClusterDescriptor - Neither the HADOOP_CONF_DIR nor the YARN_CONF_DIR environment variable is set.The Flink YARN Client needs one of these to be set to properly load the Hadoop configuration for accessing YARN. 2020-10-05 13:25:44,856 INFO org.apache.flink.yarn.AbstractYarnClusterDescriptor - Found application JobManager host name 's104' and port '32779' from supplied application id 'application_1601832819602_0001' Triggering savepoint for job 547ac058d6a84efa538be6db25a9224a. Waiting for response... Savepoint completed. Path: hdfs://s101:9000/flink/savepoints/savepoint-547ac0-92290feaf029 You can resume your program from this savepoint with the run command.
此时我们在观察一下页面:
此时我们cancel job,然后在通过刚才的savepoint重启job:
[root@s101 /usr/local/software]#flink run -s hdfs://s101:9000/flink/savepoints/savepoint-547ac0-92290feaf029 -c Stream_example.SocketWindowWordCountJavaCheckPoint FlinkExample-1.0-SNAPSHOT-jar-with-dependencies.jar 2020-10-05 13:29:37,512 INFO org.apache.flink.yarn.cli.FlinkYarnSessionCli - Found Yarn properties file under /tmp/.yarn-properties-root. 2020-10-05 13:29:37,512 INFO org.apache.flink.yarn.cli.FlinkYarnSessionCli - Found Yarn properties file under /tmp/.yarn-properties-root. 2020-10-05 13:29:37,885 INFO org.apache.flink.yarn.cli.FlinkYarnSessionCli - YARN properties set default parallelism to 2 2020-10-05 13:29:37,885 INFO org.apache.flink.yarn.cli.FlinkYarnSessionCli - YARN properties set default parallelism to 2 YARN properties set default parallelism to 2 2020-10-05 13:29:37,950 INFO org.apache.hadoop.yarn.client.RMProxy - Connecting to ResourceManager at s101/192.168.140.101:8032 2020-10-05 13:29:38,087 INFO org.apache.flink.yarn.cli.FlinkYarnSessionCli - No path for the flink jar passed. Using the location of class org.apache.flink.yarn.YarnClusterDescriptor to locate the jar 2020-10-05 13:29:38,087 INFO org.apache.flink.yarn.cli.FlinkYarnSessionCli - No path for the flink jar passed. Using the location of class org.apache.flink.yarn.YarnClusterDescriptor to locate the jar 2020-10-05 13:29:38,092 WARN org.apache.flink.yarn.AbstractYarnClusterDescriptor - Neither the HADOOP_CONF_DIR nor the YARN_CONF_DIR environment variable is set.The Flink YARN Client needs one of these to be set to properly load the Hadoop configuration for accessing YARN. 2020-10-05 13:29:38,175 INFO org.apache.flink.yarn.AbstractYarnClusterDescriptor - Found application JobManager host name 's104' and port '32779' from supplied application id 'application_1601832819602_0001' Starting execution of program
此时我们在观察一下页面:
程序继续是我们之前熟悉的样子:
其实我们可以简单理解下Savepoint的功能:Checkpoint相当于系统一直在帮你快照归档,而SavePoint是你自己手动快照归档!(可以理解为SavePoint本质就是CheckPoint)
如何理解savePoint是指向CheckPoint的指针:
OK,到这里,flink的状态管理我们就全部介绍完了,再见各位!