「Flink」Flink的状态管理与容错
在Flink中的每个函数和运算符都是有状态的。在处理过程中可以用状态来存储数据,这样可以利用状态来构建复杂操作。为了让状态容错,Flink需要设置checkpoint状态。Flink程序是通过checkpoint来保证容错,通过checkpoint机制,Flink可恢复作业的状态和计算位置。
checkpoint检查点
前提条件
Flink的checkpoin机制需要与流和状态的持久化存储交互,一般它要求:
- 一个持久化的数据源
- 当Flink程序出现问题时,可以通过checkpoint持久化存储中恢复,然后从出错的地方开始重新消费数据
- 该数据源可以在一定时间内重跑数据,例如:Kafka、RabbitMQ或者文件系统HDFS、S3、…
- 状态的持久存储
- 状态需要永久的保存下来,通常是分布式文件系统(例如:HDFS、S3、GFS、…)
启用和配置检查点
默认情况,Flink是禁用检查点。要启用检查点,调用
- // 启用检查点
- // 单位:毫秒
env.enableCheckpointing(1000);
在启用检查点时,还可以配置检查点的其他参数。
- exactly-one or at-least-once(仅一次或者至少一次)
- 大多数程序都是设置为exactly-once,只有在某些超低延迟的应用(例如:始终要求是毫秒级的应用)
- 通过查看源码,我们看到,Flink默认是 exactly-once
- public static final CheckpointingMode DEFAULT_MODE = CheckpointingMode.EXACTLY_ONCE;
- 检查点超过规定的时间就会自动终止
- 检查点之间的最小时间
- 下一个检查点将在上一个检查点完成后5秒钟启动
- 检查点最小间隔时间不会受检查点间隔更容易配置
- 检查点的并发数目。默认情况一个检查点在运行时不会触发另一个检查点,这样可以确保Flink不会花太多时间在checkpoint上,并确保流可以有效进行。
- 可以设置多个重叠的checkpoint,这对容许有一定延迟,并希望较频繁的检查(100ms)来重新处理故障是有用的
- 外部检查点
- 可以将检查点设置为外部持久化,这样检查点的元数据将写入持久存储,并且但作业运行失败是不会自动清理
- 这样可以做双重保险
- 检查点执行发生错误,是否执行任务。
- 默认情况,如果checkpoint失败,任务也将失败
- 即时最近有更多的savepoint可用于恢复,flink依然会选择使用最近一次的checkpoint来进行错误恢复
参考配置:
- // --------
- // 配置checkpoint
- // 启用检查点
- env.enableCheckpointing(1000);
- env.getCheckpointConfig().setCheckpointingMode(CheckpointingMode.EXACTLY_ONCE);
- env.getCheckpointConfig().setMinPauseBetweenCheckpoints(500);
- env.getCheckpointConfig().setCheckpointTimeout(60000);
- env.getCheckpointConfig().setMaxConcurrentCheckpoints(1);
- env.getCheckpointConfig().enableExternalizedCheckpoints(CheckpointConfig.ExternalizedCheckpointCleanup.RETAIN_ON_CANCELLATION);
- env.getCheckpointConfig().setPreferCheckpointForRecovery(true);
选择状态后端存储
Flink的checkpoint机制可以存储计时器和有状态operation的所有快照,包括:连接器、窗口或者用户自定义状态。具体checkpoint存储在哪儿(例如:是JobManager内存、文件系统或者数据库),依赖于状态后端的配置。
默认情况,状态保存在TaskManager的内存中,检查点存储在TM的内存中。为了适当地保存大状态,Flink支持其他的存储。我们可以通过:
StreamExecutionEnvironment.setStateBackend(…)
来指定存储方式
Flink状态管理
状态的应用场景:
- 当应用程序想要按照某种模式搜索某些事件时,状态可以保存迄今所有的事件序列
- 当每分钟/小时/天需要对流数据进行聚合,状态可以保存挂起的聚合
- 当在数据流上训练机器学习模型时,状态可以用来保存某一类参数的版本
- 当需要管理历史数据时,状态允许访问过去历史数据
Flink状态可以保存在堆内、或者是堆外。Flink也可以管理应用程序的状态,必要时也可以溢出到磁盘,如果应用要保持非常大的状态,可以不修改程序逻辑情况下配置状态后端存储。
Flink状态分类
Flink中有两种基本的状态:
- Keyed State
- Operator State
Keyed State
Keyed State通常和key相关,仅仅在KeyedStream的方法和算子中使用。可以把 Keyed State看作是分区,而且每一个key仅出现在一个分区内。逻辑上每个 keyed-state和唯一元组<算子并发实例, key>绑定,由于每个key仅属于算子的一个并发,因此可以简化为<算子, key>
Operator State
对于 Operator State来说,每个Operator State和一个并发实例绑定。Kafka connector是Flink中使用operator state的一个很好的示例。每个Kafka消费者的并发在Operator State中维护一个 topic partition到offset的映射关系。
Operator state在Flink作业的并发改变后,会重新分发状态,分发的策略和keyed stated不一样。
Raw State与Managed State
Keyed Stated和Operator State分别有两种形式:managed 和 raw
Managed State是由Flink运行时管理的数据结构来表示的,例如:内部的Hash Table或者RocksDB。例如:ValueState、ListState等。Flink运行时会对这些状态进行编码并写入Checkpoint。
Raw State则保存在自己的数据结构中。checkpoint的时候,Flink并不知道状态里面具体的内容,仅仅写入一串字节序列到checkpoint中。
所有的DataStream的function都可以使用managed state,但raw state只能在实现算子时使用。由于Flink可以在修改并发时更好的分发状态数据,并且能够更好的管理内存,因为讲义使用 managed state.
使用Managed Keyed State
Managed keyed state接口提供不同类型的状态访问接口,这些状态都作用在当前输入数据的key下。这些状态仅可在KeyedStream上使用,可以通过 stream.keyBy(…)得到KeyedStream。
所有支持的状态类型如下:
- ValueState<T>
- 保存一个可以更新和获取的值,算子接收到的每个key都可能对应一个值
- 可以通过update(T)进行更新,通过value()获取
- ListState<T>
- 保存一个元素的列表,可以往这个列表中追加数据,并在当前列表上检索
- 可以通过 add(T)或者addAll(List<T>)进行追加元素
- 通过get()获取整个列表
- 通过 update(List<T>)覆盖当前列表
- ReducingState<T>
- 保存一个单值,表示添加到状态的所有值的聚合。接口与ListState类似
- AggregatingState<IN, OUT>
- 保存一个单值,表示添加到状态的所有值的聚合
- 与ReducingState相反的是,聚合类型可能与添加到状态的元素类型不同。接口与ListState类似
- FoldingState<T, ACC>(后续将过期)
- 保存一个单值,白搜狐添加到状态的所有值的集合
- 与ReducingState相反的是,聚合类型可能与添加到状态的元素类型不同。接口与ListState类似
- MapState<UK, UV>
- 维护一个映射列表,可以添加键值到状态中,可以获取当前映射的迭代器
- 使用put、putAll添加映射,使用 get检索特定key
注意:
- 这些状态对象仅用于状态交互。状态本身不一定存储在内存中,还有可能保存在磁盘或者其他位置
- 从状态中获取的值取决于输入元素说代表的key,因此,在不同key上调用同一个接口,可能得到不同的值
使用Managed Operator State
可以通过实现 CheckpointedFunction 或者 ListCheckpointed<T extends Serialized>接口来使用Managed Operator State。
CheckpointedFunction接口:
- void snapshotState(FunctionSnapshotContext context) throws Exception;
- void initializeState(FunctionInitializationContext context) throws Exception;
在Flink进行checkpoint时,会调用snapshotstate(),用户自定义函数初始化时会调用 initializeState。初始化包括第一次自定义函数初始化和从之前的 checkpoint 回复。因此,initializeState 中应该也包括状态恢复的逻辑。
Managed Operator State以list的形式存在,这些状态是一个可序列化对象的集合List,彼此独立,方便在改变并发后进行状态的重新分派。换句话说,这些对象是重新分配 non-keyed state的最细粒度。根据状态的不同访问方式,有以下两种分配模式:
- Even-split redistribution
- 每个算子都存储一个列表形式的状态集合,整个状态由所有的列表拼接而成
- 但作业恢复或者重新分配时,整个状态按照算子的并行度均匀分配
- Union redistribution
- 每个算子保存一个列表形式的状态集合,整个状态由所有的列表拼接而成
- 但作业恢复或者重新分配时,每个算子都将获得所有的状态数据
ListCheckpointed接口:
ListCheckpointed接口是CheckpointedFunction接口的精简版,仅支持 even-split redistribution的list state
- List<T> snapshotState(long checkpointId, long timestamp) throws Exception;
- void restoreState(List<T> state) throws Exception;
snapshotState()需要返回一个将写入到checkpoint的对象列表, restoreState则需要处理恢复回来的对象列表。
参考文献:
Flink官方文档:
https://ci.apache.org/projects/flink/flink-docs-release-1.9/zh/dev/stream/state/checkpointing.html
https://ci.apache.org/projects/flink/flink-docs-release-1.9/zh/ops/state/checkpoints.html
https://ci.apache.org/projects/flink/flink-docs-release-1.9/zh/dev/stream/state/state.html
「Flink」Flink的状态管理与容错的更多相关文章
- 总结Flink状态管理和容错机制
本文来自8月11日在北京举行的 Flink Meetup会议,分享来自于施晓罡,目前在阿里大数据团队部从事Blink方面的研发,现在主要负责Blink状态管理和容错相关技术的研发. 本文主要内容如 ...
- Flink状态管理和容错机制介绍
本文主要内容如下: 有状态的流数据处理: Flink中的状态接口: 状态管理和容错机制实现: 阿里相关工作介绍: 一.有状态的流数据处理# 1.1.什么是有状态的计算# 计算任务的结果不仅仅依赖于输入 ...
- 大数据计算引擎之Flink Flink状态管理和容错
这里将介绍Flink对有状态计算的支持,其中包括状态计算和无状态计算的区别,以及在Flink中支持的不同状态类型,分别有 Keyed State 和 Operator State .另外针对状态数据的 ...
- 「Flink」Flink 1.9 WebUI运行作业界面分析
运行作业界面 在以下界面中,可以查看到作业的名称.作业的启动时间.作业总计运行时长.作业一共有多少个任务.当前正在运行多少个任务.以及作业的当前状态. 这里的程序:一共有17个任务,当前正在运行的是1 ...
- 「Flink」Flink中的时间类型
Flink中的时间类型和窗口是非常重要概念,是学习Flink必须要掌握的两个知识点. Flink中的时间类型 时间类型介绍 Flink流式处理中支持不同类型的时间.分为以下几种: 处理时间 Flink ...
- 「SpringBoot」如何优雅地管理SpringBoot项目
本文主要讲述一下如何优雅地管理SpringBoot项目. 背景 课堂上,当小明形如流水地回答完沐芳老师提出来的问题时,却被至今没有对象的胖虎无情嘲讽了? 沐芳老师:小明,你平时是如何启动.停止你的Sp ...
- Flink架构(四)- 状态管理
状态管理 之前我们提到过大多数流应用是有状态的.很多operators会不断的访问并更新某中状态,例如一个window中收集了多少条记录,输入源中当前读到的位置,亦或是用户定义的特定operators ...
- Flink状态管理与状态一致性(长文)
目录 一.前言 二.状态类型 2.1.Keyed State 2.2.Operator State 三.状态横向扩展 四.检查点机制 4.1.开启检查点 (checkpoint) 4.2.保存点机制 ...
- Flink的状态管理与恢复机制
参考地址:https://www.cnblogs.com/airnew/p/9544683.html 问题一.什么是状态? 问题二.Flink状态类型有哪几种? 问题三.状态有什么作用? 问题四.如何 ...
随机推荐
- xlwings excel(四)
前言 当年看<别怕,Excel VBA其实很简单>相见恨晚,看了第一版电子版之后,买了纸质版,然后将其送人.而后,发现出了第二版,买之收藏.之后,发现Python这一编程语言,简直是逆天, ...
- 深入理解Java虚拟机:JVM高级特性与最佳实践
第一部分走近Java第1章走近Java21.1概述21.2Java技术体系31.3Java发展史51.4Java虚拟机发展史91.4.1SunClassicExactVM91.4.2SunHotSpo ...
- 20200104模拟赛 问题C 上台拿衣服
题目 分析: 乍一看不就是从楼上扔鸡蛋那道题吗... 然后开始写写写... 设f [ i ] [ j ]表示 i 个记者膜 j 次可以验证多少层楼... 于是开始递推: 我们选取第 i 个记者去尝试其 ...
- Doxygen -- part 2
Documenting the code 这个章节涵盖两个主题: 如何在你的代码中放置注释, 一遍doxygen可以在生成的文档中囊括它们. 如何组织一个注释块的内容, 以使得输出美观. 特殊注释块 ...
- Linux网络文件共享服务之smaba
一.SAMBA服务简介 samba是1991年由Andrew Tridgel开发实现,主要用于Windows和unix文件共享.samba实现了共享文件和打印,实现在线编辑,登录SAMBA用户的身份认 ...
- 谈谈模型融合之三 —— GBDT
前言 本来应该是年后就要写的一篇博客,因为考完试后忙了一段时间课设和实验,然后回家后又在摸鱼,就一直没开动.趁着这段时间只能呆在家里来把这些博客补上.在之前的文章中介绍了 Random Forest ...
- Day7-Python3基础-面向对象进阶
内容: 面向对象高级语法部分异常处理 经典类vs新式类 静态方法.类方法.属性方法 类的特殊方法 反射 Socket开发基础 面向对象高级语法部分 静态方法 通过@staticmethod ...
- linux pycharm 安装
Ubuntu安装之python开发 什么??公司要用Ubuntu(乌班图)?不会用??怎么进行python开发??? 乌班图操作系统下载地址:http://releases.ubuntu.com/ ...
- Java小白入门:聊聊Java这门编程语言
一.什么叫做编程 首先我们应该了解一下什么叫做编程. 百度百科词条的解释: 编程是编定程序的简称,是让计算机代我们解决某个问题,是对某个计算体系规定一定的运算方式,使计算体系按照该计算方式运行,并最终 ...
- Git详解之常用命令
注意:此篇文章中的绝大部分内容来自摘抄,查阅人员请注意