西安网站代维护,移动互联网开发的前景,平面设计培训班学费一般多少百度贴吧,化工行业网站设计Flink处理机制的核心就是“有状态的流处理”#xff0c;在某些情况下#xff0c;一条数据的计算不仅要基于当前数据自身#xff0c;还需要依赖数据流中的一些其他数据。这些在一个任务中#xff0c;用来辅助计算的数据我们就称之为这个任务的状态。
一、按键分区状态… Flink处理机制的核心就是“有状态的流处理”在某些情况下一条数据的计算不仅要基于当前数据自身还需要依赖数据流中的一些其他数据。这些在一个任务中用来辅助计算的数据我们就称之为这个任务的状态。
一、按键分区状态KeyedState分类 按键分区状态是根据输入流中定义的key来进行维护和访问的所有是定义在KeyedStream中的也就是对datastream进行keyby之后才能使用按键分区状态。 按键分区状态支持的结构类型主要有以下几种
1ValueState值状态 顾名思义 就是状态只保存一个值这个值的类型可以是任何具体的数据类型。如ValueStateLong。
publice interface ValueStateT extends State {T value(); // 获取当前状态的值void update(T value); // 对状态进行更新
}
2ListState列表状态 以列表的形式保存数据。
publice interface ListStateT extends State {IterableT get(); // 获取当前的列表状态 是一个可迭代对象void update(ListT values); // 传入一个列表对列表状态进行覆盖更新void add(T value); // 在状态列表中添加一个元素void addAll(ListT values); //添加多个元素
}
3MapState映射状态 把键值对作为状态保存起来。
publice interface MapStateK, V extends State {V get(K key); // 获取传入key对应的value值void put(K key, V value); //更新key对应的valuevoid putAll(MapK, V map);void remove(K key); boolean contains(K key);IterableMap.EnterK, V entries();IterableK keys();IterableV values();boolean isEmpty();
}
4ReducingState归约状态 归约状态保存的是进行归约计算后的结果值也就是每add一个元素都进行归约计算并将归约结果保存为当前状态值因此需要在归约状态描述器中声明一个归约函数。
5AggregatingState聚合状态) 聚合状态与归约状态类似聚合状态也是一个值只不过聚合状态描述器传入的是一个更加一般化的聚合函数可以重新定义中间状态和输出状态的类型。
二、状态生存时间TTLtime-to-live 在实际应用中状态会随着时间的推移而逐渐增多如果不加以限制最终就会导致存储空间的耗尽。Flink可以为状态配置“生存时间”当状态在内存中存活的时间超过设定的值时就将他清除掉调用clear方法可以清除状态。 但是如果额外开启一个进程不断扫描所有的状态是否过期会占用大量资源且很多情况下是无用功一个比较好的方法是状态失效的时候不立即删除之后如果有对这个状态进行访问再判断是否已经失效、从而进行清除则不需要另外开启进程进行扫描了。 配置状态的TTL时首先需要创建一个StateTtlConfig配置对象然后调用状态描述器.enableTimeToLive()方法启动TTL功能。
StateTtlConfig ttlConfig StateTtlConfig.newBuilder(Time.seconds(10)).setUpdateType(StateTtlConfig.UpdateType.OnCreateAndWrite)//创建状态和更新状态时才更新失效时间.setStateVisibility(StateTtlConfig.StateVisibility.NeverReturnExpired)//不返回过期值.build();ValueStateDescriptorString stateDescriptor new ValueStateDescriptor(my_state, String.class);stateDescriptor.enableTimeToLive(ttlConfig)
三、算子状态分类 算子状态针对当前算子任务有效不对key进行隔离与key无关因此一个并行子任务上的不同key会访问到相同的算子状态。
1ListState列表状态 与上面类似。差别主要在于重分区时按键分区状态的ListState是以keyGrouo的形式重新均衡发送到下游的而算子状态的ListState是将所有数据收集到一起均匀分配。
2UnionListState联合列表状态 与ListState类似。差别主要在于重分区时是将所有的状态一起发送到下游的每一个并行子任务上列表状态太大时效率很低不建议使用。
3BroadcastState广播状态 对所有的并行子任务保持同一份“全局”状态一般用来做统一的规则或配置设定。这时所有的并行子任务都将访问同一个状态就像是状态被广播了注意没有真正广播。 广播状态必须基于广播流来创建。
4算子状态的持久化保存 与按键分区状态相比算子状态的故障后重新恢复稍显复杂因为故障重启后可能发生并行度调整按键分区状态中相同的key仍然可以被分配到一个子任务上然而算子状态下的数据所发往的分区可能会发生变化那么如何保证原先的状态与故障恢复后数据的对应关系呢 Flink提供了CheckpointedFunction接口让我们可以根据业务需求自行设计状态的保存和恢复逻辑这里就不展开说了。
四、状态持久化和状态后端
1开启检查点 对状态进行持久化保存可以在发生故障后进行重启恢复 。Flink对状态进行持久化的方式就是将状态写入检查点保存到外部存储系统中。具体的存储介质一般是分布式文件系统。因此要相对状态进行自动持久化保存首先就要开启检查点。调用执行环境的.enableCheckpointing()方法就可以开启检查点。
env.enableCheckpointing(1000); //每隔1s保存检查点
2检查点的保存流程 检查点的保存主要是JobManager TaskManager和外部存储系统三者之间的协调。具体来说 在应用触发检查点保存时首先由JobManager向每个TaskManager发送触发检查点命令TaskManager收到命令后对当前任务的状态进行快照保存持久化到远程的存储介质完成后向JobManager返回确认消息JobManager只有收到所有TaskManager确认消息才会确认当前检查点保存成功。而这一切工作的协调就需要一个“专职人员”来完成也就是状态后端。 3状态后端state backends 状态后端就是Flink中负责状态的存储、访问以及维护的一个可插拔组件主要负责两件事一是本地的状态管理而是将检查点写入远程的持久化介质。 状态后端可以分为两类默认哈希表状态后端HashMapStateBackend、内嵌RocksDB状态后端EmbeddedRocksDBStateBackend。可以通过对执行环境调用.setStateBackend()方法设置状态后端类型。
env.setStateBackend(new HashMapStateBackend());env.setStateBackend(new EmbeddedRocksDBStateBackend()); 哈希表状态后端优点本地状态放入内存读写效率高 内嵌RocksDB状态后端优点异步快照增量式保存检查点机制