问题:
1.为什么需要State
2.什么是State
3.什么是Barrier
4.State如何分类的
5.支持哪几种后端
什么是CheckPoint机制
为了保障数据的两种语义(至少一次或仅有一次),以及尽快从最新的位置恢复,避免从头开始计算。CheckPoint机制是在指定时间间隔对流上的状态做一次快照,记录信息如下:
1.数据源(例如Kafka)中消息的offset
2.所有状态的operator当前的状态信息(例如sum中的数值)
什么是State
纯流式处理(Flink)对于数据需要源源不断的处理,对State的需求要比微批模式(Spark)要高
Flink中有两种基本类型的State,即Keyed State和Operator State。
State的数据结构如下:
1.ValueState:即类型为T的单值状态。这个状态与对应的key绑定,是最简单的状态了。它可以通过update方法更新状态值,通过value()方法获取状态值
2. ListState:即key上的状态值为一个列表。可以通过add方法往列表中附加值;也可以通过get()方法返回一个Iterable来遍历状态值
3. ReducingState:这种状态通过用户传入的reduceFunction,每次调用add方法添加值的时候,会调用reduceFunction,最后合并到一个单一的状态值
4. MapState<UK, UV>:即状态值为一个map。用户通过put或putAll方法添加元素
注意:State对象通过RuntimeContext的接口获取到,当然不同类型的state,对应于不同的接口; 关键是,如果要使用state,必须要使用RichFlatMapFunction,用普通的function是无法获取到的
State存到哪里
1.MemoryStateBackend
优点:state数据保存在taskmanager的内存中,执行checkpoint的时候,会把state的快照数据保存到JobManager里,这种Backend很轻量级、不需要额外的依赖,但是不具备高可用,并且只支持State很小的场景。
2.FsStateBackend
state数据保存在taskmanager的内存中,执行checkpoint的时候,会把state的快照数据保存到配置的文件系统中,可以使用hdfs等分布式文件系统。
3.RockDBStateBackend
RocksDB跟上面的都略有不同,它会在本地文件系统中维护状态,state会直接写入本地rocksdb中。同时RocksDB需要配置一个远端的filesystem。
uri(一般是HDFS),在做checkpoint的时候,会把本地的数据直接复制到filesystem中。fail over的时候从filesystem中恢复到本地。
RocksDB克服了state受内存限制的缺点,同时又能够持久化到远端文件系统中,比较适合在生产中使用
如何实现
采用改进的Chandy-Lamport算法来实现分布式快照
核心的元素:Barrier
如何设置
默认checkpoint功能是disabled的,想要使用的时候需要先启用
checkpoint开启之后,默认的checkPointMode是Exactly-once
checkpoint的checkPointMode有两种,Exactly-once和At-least-once
Exactly-once对于大多数应用来说是最合适的。At-least-once可能用在某些延迟超低的应用程序(始终延迟为几毫秒)
// 每隔1000 ms进行启动一个检查点【设置checkpoint的周期】
env.enableCheckpointing(1000);
// 高级选项:
// 设置模式为exactly-once (这是默认值)
env.getCheckpointConfig().setCheckpointingMode(CheckpointingMode.EXACTLY_ONCE);
// 确保检查点之间有至少500 ms的间隔【checkpoint最小间隔】
env.getCheckpointConfig().setMinPauseBetweenCheckpoints(500);
// 检查点必须在一分钟内完成,或者被丢弃【checkpoint的超时时间】
env.getCheckpointConfig().setCheckpointTimeout(60000);
// 同一时间只允许进行一个检查点
env.getCheckpointConfig().setMaxConcurrentCheckpoints(1);
// 表示一旦Flink处理程序被cancel后,会保留Checkpoint数据,以便根据实际需要恢复到指定的 Checkpoint【详细解释见备注】
env.getCheckpointConfig().enableExternalizedCheckpoints(ExternalizedCheckpointCleanup.RETAIN_ON_CANCELLATION);
//cancel处理选项:
//(1)ExternalizedCheckpointCleanup.RETAIN_ON_CANCELLATION:
//表示一旦Flink处理程序被cancel后,会保留Checkpoint数据,以便根据实际需要恢复到指定
//的Checkpoint
//(2)ExternalizedCheckpointCleanup.DELETE_ON_CANCELLATION:
//表示一旦Flink处理程序被cancel后,会删除Checkpoint数据,只有job执行失败的时候才会
//保存checkpoint
后端设置
1.单任务
修改当前任务代码
env.setStateBackend(new FsStateBackend("hdfs://namenode:9000/flink/checkpoints"));
//或者new MemoryStateBackend()
//或者new RocksDBStateBackend( hdfs->url, true);【需要添加第三方依赖】
2.全局
修改flink-conf.yaml
state.backend: filesystem
state.checkpoints.dir: hdfs://namenode:9000/flink/checkpoints
注意:state.backend的值可以是下面几种:jobmanager(MemoryStateBackend), filesystem(FsStateBackend), rocksdb(RocksDBStateBackend)