您的位置:首页 > 其它

Flink(四)Flink的State

2021-01-05 18:40 288 查看

一、State概述

Flink里面有state的概念
State:一般指一个具体的task/operator的状态。State可以被记录,在失败的情况下数据还可以恢复,Flink中有两种基本类型的State:Keyed State,Operator State,他们两种都可以以两种形式存在:原始状态(raw state)和托管状态(managed state)
托管状态:由Flink框架管理的状态,我们通常使用的就是这种。
原始状态:由用户自行管理状态具体的数据结构,框架在做checkpoint的时候,使用byte[]来读写状态内容,对其内部数据结构一无所知。通常在DataStream上的状态推荐使用托管的状态,当实现一个用户自定义的operator时,会使用到原始状态。但是我们工作中一般不常用,所以我们不考虑他。

二、State类型

1、Operator State类型

里面没有shuffle的操作,或者说里面没有key by的操作。

(1)operator state是task级别的state,说白了就是每个task对应一个state

(2)Kafka Connector source中的每个分区(task)都需要记录消费的topic的partition和offset等信息。
(3)operator state 只有一种托管状态:ValueState
(4)operator state可以定义为source和sink的状态进行管理

2、Keyed State类型

(1)keyed state记录的是每个key的状态
(2)Keyed state托管状态有六种类型

(2.1)ValueState
/**
*  ValueState<T> :这个状态为每一个 key 保存一个值
*      value() 获取状态值
*      update() 更新状态值
*      clear() 清除状态
*/
(2.2)ListState
/**
*  ListState<T> :这个状态为每一个 key 保存集合的值
*      get() 获取状态值
*      add() / addAll() 更新状态值,将数据放到状态中
*      clear() 清除状态
*/
(2.3)MapState
/**
*  MapState<K, V> :这个状态为每一个 key 保存一个 Map 集合
*      put() 将对应的 key 的键值对放到状态中
*      values() 拿到 MapState 中所有的 value
*      clear() 清除状态
*/
(2.4)ReducingState
/**
*  ReducingState<T> :这个状态为每一个 key 保存一个聚合之后的值
*      get() 获取状态值
*      add()  更新状态值,将数据放到状态中
*      clear() 清除状态
*/
(2.5)AggregatingState

(2.6)FoldingState
(3) flink的keyed的state通过继承RichFlatMapFunction,重写open和flatMap,定义状态,实现状态的管理和自定义

三、State backend

1、概述

Flink支持的StateBackend:
MemoryStateBackend
FsStateBackend
RocksDBStateBackend

(1)、MemoryStateBackend


默认情况下,状态信息是存储在 TaskManager 的堆内存中的,checkpoint 的时候将状态保存到JobManager 的堆内存中。
缺点:
只能保存数据量小的状态
状态数据有可能会丢失
优点:
开发测试很方便

(2)、 FSStateBackend

状态信息存储在TaskManager 的堆内存中的,checkpoint 的时候将状态保存到指定的文件中 (HDFS等文件系统)
缺点:
状态大小受TaskManager内存限制(默认支持5M)
优点:
状态访问速度很快
状态信息不会丢失
用于: 生产,也可存储状态数据量大的情况

(3)、 RocksDBStateBackend


状态信息存储在 RocksDB 数据库 (key-value 的数据存储服务), 最终保存在本地文件中
checkpoint 的时候将状态保存到指定的文件中 (HDFS 等文件系统)
缺点:
状态访问速度有所下降
优点:
可以存储超大量的状态信息
状态信息不会丢失
用于: 生产,可以存储超大量的状态信息

2、 StateBackend配置方式

(1)单任务调整

修改当前任务代码 env.setStateBackend(new    FsStateBackend("hdfs://namenode:9000/flink/checkpoints")); 或者new MemoryStateBackend() 或者new RocksDBStateBackend(filebackend, true);【需要添加第三方依赖】

(2)全局调整

修改flink-conf.yaml state.backend: filesystem state.checkpoints.dir: hdfs://namenode:9000/flink/checkpoints 注意:state.backend的值可以是下面几种:jobmanager(MemoryStateBackend), filesystem(FsStateBackend), rocksdb(RocksDBStateBackend)

四、checkpoint(容错)

1、checkpoint概述

(1)为了保证state的容错性,Flink需要对state进行checkpoint。 (2)Checkpoint是Flink实现容错机制最核心的功能,它能够根据配置周期性地基于Stream中各个
Operator/task的状态来生成快照,从而将这些状态数据定期持久化存储下来,当Flink程序一旦意外崩
溃时,重新运行程序时可以有选择地从这些快照进行恢复,从而修正因为故障带来的程序数据异常
(3)Flink的checkpoint机制可以与(stream和state)的持久化存储交互的前提:
持久化的source,它需要支持在一定时间内重放事件。这种sources的典型例子是持久化的消息队列
(比如Apache Kafka,RabbitMQ等)或文件系统(比如HDFS,S3,GFS等)
用于state的持久化存储,例如分布式文件系统(比如HDFS,S3,GFS等)
生成快照:5秒

恢复快照:

2、checkpoint配置

默认checkpoint功能是disabled的,想要使用的时候需要先启用,checkpoint开启之后,
checkPointMode有两种,Exactly-once和At-least-once,默认的checkPointMode是Exactly-once,
Exactly-once对于大多数应用来说是最合适的。At-least-once可能用在某些延迟超低的应用程序(始终延迟为几毫秒)。

默认checkpoint功能是disabled的,想要使用的时候需要先启用
StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
// 每隔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(ExternalizedCheckpointCl
eanup.RETAIN_ON_CANCELLATION);

3、恢复数据(容错)

(1)重启策略概述

Flink支持不同的重启策略,以在故障发生时控制作业如何重启,集群在启动时会伴随一个默认的重启策略,在没有定义具体重启策略时会使用该默认策略。 如果在工作提交时指定了一个重启策略,该策略会覆盖集群的默认策略,默认的重启策略可以通过 Flink 的配置文件 flink-conf.yaml 指定。配置参数restart-strategy 定义了哪个策略被使用。
常用的重启策略
(1.1)固定间隔 (Fixed delay)
(1.2)失败率 (Failure rate)
(1.3)无重启 (No restart)
如果没有启用 checkpointing,则使用无重启 (no restart) 策略。
如果启用了 checkpointing,但没有配置重启策略,则使用固定间隔 (fixed-delay) 策略, 尝试重启次数默认值是:Integer.MAX_VALUE,重启策略可以在flink-conf.yaml中配置,表示全局的配置。也可以在应用代码中动态指定,会覆盖全局配置。

(2)重启策略

(2.1)固定间隔 (Fixed delay)

第一种:全局配置 flink-conf.yaml
restart-strategy: fixed-delay
restart-strategy.fixed-delay.attempts: 3
restart-strategy.fixed-delay.delay: 10 s
第二种:应用代码设置
env.setRestartStrategy(RestartStrategies.fixedDelayRestart( 3, // 尝试重启的次数
Time.of(10, TimeUnit.SECONDS) // 间隔 ));

(2.2)失败率 (Failure rate)

第一种:全局配置 flink-conf.yaml
restart-strategy: failure-rate
restart-strategy.failure-rate.max-failures-per-interval: 3
restart-strategy.failure-rate.failure-rate-interval: 5 min
restart-strategy.failure-rate.delay: 10 s
第二种:应用代码设置
env.setRestartStrategy(RestartStrategies.failureRateRestart( 3, // 一个时间段内的最大失败次数
Time.of(5, TimeUnit.MINUTES), // 衡量失败次数的是时间段
Time.of(10, TimeUnit.SECONDS) // 间隔 ));

(2..3)无重启 (No restart)

第一种:全局配置 flink-conf.yaml
restart-strategy: none 第二种:应用代码设置
env.setRestartStrategy(RestartStrategies.noRestart());

4、多checkpoint

默认情况下,如果设置了Checkpoint选项,则Flink只保留最近成功生成的1个Checkpoint,而当Flink程序失败时,可以从最近的这个Checkpoint来进行恢复。但是,如果我们希望保留多个Checkpoint,并能够根据实际需要选择其中一个进行恢复,这样会更加灵活,比如,我们发现最近4个小时数据记录处理有问题,希望将整个状态还原到4小时之前Flink可以支持保留多个Checkpoint,需要在Flink的配置文件conf/flink-conf.yaml中,添加如下配置,指定最多需要保存Checkpoint的个数:

state.checkpoints.num-retained: 20

这样设置以后就查看对应的Checkpoint在HDFS上存储的文件目录

hdfs dfs -ls hdfs://namenode:9000/flink/checkpoints

如果希望回退到某个Checkpoint点,只需要指定对应的某个Checkpoint路径即可实现

5、从checkpoint恢复数据

如果Flink程序异常失败,或者最近一段时间内数据处理错误,我们可以将程序从某一个Checkpoint点进行恢复

bin/flink run -s hdfs://namenode:9000/flink/checkpoints/467e17d2cc343e6c56255d222bae3421/chk- 56/_metadata flink-job.jar
### ```

-----

程序正常运行后,还会按照Checkpoint配置进行运行,继续生成Checkpoint数据。
当然恢复数据的方式还可以在自己的代码里面指定checkpoint目录,这样下一次启动的时候即使代码发生了改变就自动恢复数据了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: