1、每一个算子在启动时,都会先Flink集群,注册自己的状态 2、这个状态,最初放在内存,会被持久化到磁盘,或者数据库 3、每次我接受到数据,需要计算的时候,会在拿到数据之后,先去获取存储在内存中的状态,(比如我在求和,我就会先把状态里面的结果拿出来,然后跟现在的累加) 4、拿到状态,进行运算,算完,去更新状态,然后数据继续往下走 补充: - 状态不能跨任务访问,状态跟特定的算子关联 - 算子需要预先注册其状态 注册个Flink - 一个并行度里面都有一个分区状态
1、某个算子或者key当前的状态,因为处理的是实时数据,我们需要对这个状态进行操作或者管理
2、 分类 算子的分类
Operator State 每个并行度存储一个状态
状态对同一个子任务而言,是共享的,也只能被同一个子任务所访问只要在同一个分区,不管key是什么 访问的都是同一个状态
Keyed State 根据输入数据流中定义的键(key)来维护和访问
首先得有keyby操作根据key,来保存状态(可能一个分区(task)里面存储不止一个key(有几个key 就有几个keyState))
3、两种状态的区别
4、分类 算子的管理
managed state Flink 管理 调用API即可raw state 自己管理 容错机制
简介Apache Flink提供了一种容错机制,可以持续恢复数据流应用程序的状态。该机制确保即使出现故障,经过恢复,程序的状态也会回到以前的状态。Flink支持at least once语义和exactly once语义Flink通过定期地做checkpoint来实现容错和恢复,容错机制不断地生成数据流的快照。对于小状态的流应用程序,这些快照非常轻量级并且可以经常生成快照,而不会对性能产生太大的影响。流应用程序的状态存储在一个可配置的地方(例如主节点或HDFS)。如果出现程序故障(由于机器、网络或软件故障),Flink将停止分布式流数据流。然后系统重新启动operator,并将其设置为最近一批的检查点。注意:
默认情况下,禁用checkpoint(检查点)要使得容错机制正常运行,数据流source需要能够将流倒回到指定的之前的点。比如Apache Kafka有这种方法,flink与Kafka的connector可以利用重置kafka topic的偏移量来达到数据重新读取的目的。 Barriers(栅栏)
这里说的 是并行的场景(也基本不会只有一个分区的)
Flink的分布式快照的核心元素是stream barriers。这些barriers被注入到数据流中,作为数据流的一部分和其他数据一同流动,barriers不会超过其他数据提前到达(乱序到达)。一个Barrier将数据流中的数据分割成两个数据集,即进入当前快照的数据和进入下一次快照的数据。每个Barrier带有一个ID,该ID为将处于该Barrier之前的数据归入快照的检查点的ID。Barrier不会打断数据流的流动,所以它是十分轻量级的。来自不同的快照的多个Barrier可以同一时间存在于同一个流中,也就是说,不同的快照可以并行同时发生。如下图所示:
Barrier是在source处被插入到数据流中的。快照n的barrier被插入的点(记为Sn),这个点就是在源数据流中快照n能覆盖到的数据的最近位置。如在Apache Kafaka中,这个位置就是上一个数据(record)在分区(partition)中的偏移量(offset)。这个位置Sn将会交给checkpoint 协调器(它位于Flink的JobManager中)。这些Barrier随数据流流动向下游,当一个中间Operator在其输入流接收到快照n的barrier时,它在其所有的输出流中都发送一个快照n的Barrier。当一个sinkoperator(流DAG的终点)从其输入流接收到n的Barrier,它将快照n通知给checkpoint coordinator(协调器)。在所有Sink都通知了一个快照后,这个快照就完成了。当快照n完成后,由于数据源中先于Sn的的数据已经通过了整个data flow topology,我们就可以确定不再需要这些数据了。 Checkpoints
默认情况下,flink禁用检查点。
1、这里要分两种情况,一种是只有一次,一种最少一次 2、只有一次: 1)、当不同的数据源,流到Barriers时,会进入等待状态,等待其他并行的数据源全部来到,一起拍快照 2)、此时后面在到来的是数据就说属于下一个checkpoint 所以会暂时进入缓冲区 3)、算子之间,分区不改变的时候,谁先到了栅栏处(每一个并行度里面都会有栅栏),谁就拍照,拍完先把结果放到taskManager,然后需要持久化的时候走状态后端 快照的映射信息由jobManger通一管理 4)、补充:这里的jobManager 会对你的快照进行管理,把他们收集到一起,方便恢复(其他只是把元数据记录在一起) 2、最少一次: 1)、当不同分区的数据来临之后,各自拍快照,然后广播下去 就继续数据的传输,如果出现了错误,就需要从上一个数据源重新发送数据,这也就形成了最少一次恢复Recovery
link恢复时的机制是十分直接的:在系统失效时,Flink选择最近的已完成的检查点k,系统接下来重部署整个数据流图,然后给每个Operator在检查点k时的相应状态。数据源则被设置为从数据流的Sk位置开始读取。例如,在Apache Kafka执行恢复时,系统会通知消费者从偏移Sk开始获取数据。这里的数据源,最好还是持续的数据源,比如消息队列(例如,Apache Kafka,RabbitMQ)或文件系统(例如,HDFS,S3,GFS,NFS,Ceph,…)。 State Backends -->后端状态 状态的存储地
Flink 在保存状态时,支持三种存储方式,如下:
MemoryStateBackend (基于内存存储)
快速,低延迟,但不稳定状态存在taskManager内存里,checkpoint存在 jobManager内存里一般做测试用,实际生产环境不用
FsStateBackend (基于文件系统存储)
本地状态存在taskManager内存里,checkpoint文件系统里实际生产会使用
RocksDBStateBackend (基于RocksDB数据库存储)
实际生产会使用做序列化后,存在本地的RocksDB里面每次只记录发生变更的数据读写,访问速度会慢点
补充:如果没有配置其他任何内容,系统默认将使用MemoryStateBackend。
如有不同见解,欢迎交流!



