环境
- Flink:1.6.1
- Scala:2.11.12
- jdk1.8
Hello World
package flink
import org.apache.flink.core.fs.Path
import org.apache.flink.runtime.state.StateBackend
import org.apache.flink.runtime.state.filesystem.FsStateBackend
import org.apache.flink.streaming.api.environment.CheckpointConfig.ExternalizedCheckpointCleanup
import org.apache.flink.streaming.api.scala._
object HelloWorld {
def main(args: Array[String]): Unit = {
val env: StreamExecutionEnvironment = StreamExecutionEnvironment.getExecutionEnvironment
// Change backend location
val cpp = new Path("file:///tmp/state.backend")
val fsBackend: StateBackend = new FsStateBackend(cpp)
env.setStateBackend(fsBackend)
// Enable checkpoint in millis
env.enableCheckpointing(1000)
// Default delete on cancellation
env.getCheckpointConfig.enableExternalizedCheckpoints(ExternalizedCheckpointCleanup.RETAIN_ON_CANCELLATION)
val text = env.socketTextStream("localhost", 9000, '\n')
val counts = text
.flatMap { _.toLowerCase.split("\\W+").filter(_.nonEmpty) }
.map { (_, 1) }
.keyBy(0)
.sum(1)
.print()
.setParallelism(1)
env.execute("Socket WordCount")
}
}
运行
直接在IDE运行,或通过flink run
命令运行到flink
集群
本地单机集群
- 下载解压
$ tar xzf flink-*.tgz # Unpack the downloaded archive
$ cd flink-1.6.1
- 运行
$ ./bin/start-cluster.sh # Start Flink
- WEB UI
http://localhost:8081
运行到集群
mvn clean package
flink run -c flink.HelloWorld target/scala-flink-0.1.jar
在WEB UI查看
自动创建的检查点(checkpoints)路径(注意:多了个JobID的子目录)
需要在代码自动创建检查点的时间间隔(还可以设置取消任务是否保留检查点,默认任务取消后删除检查点)
手动创建保存点(Savepoints)
flink savepoint 17b840a3d2221b1400ec03f7e3949b17 /tmp/state.backend/s1
结果
恢复检查点(Checkpoints)/保存点(Savepoints)
检查点和保存点的恢复方法一样的
# savepoint
flink run -s /tmp/state.backend/s1/savepoint-17b840-2cfe3bd5bc0c -c flink.HelloWorld target/scala-flink-0.1.jar
# checkpoint
flink run -s /tmp/state.backend/17b840a3d2221b1400ec03f7e3949b17/chk-960 -c flink.HelloWorld target/scala-flink-0.1.jar
总结
检查点(checkpoint)的目录是依赖JobID的,每次运行任务都是一个唯一的JobID(好像不能手动设置),所以要找到上一次任务的JobID才能找到检查点。
保存点(savepoint)需要手动触发,而且在指定目录下还生成一个唯一的子目录。
如果可以手动指定JobID,则可以在任务失败后,简单的重新执行任务即可恢复到失败前的检查点。
例如Kafka Streams是通过application-id
来保存、区分任务的数据,任务重新运行会读取对应application-id
里的数据,从而在上一次的状态下继续运行。