数据的相关时间包括:
- event-time:事件产生的时间,也可以理解成业务时间。
- ingestion-time:进入Flink的时间。如果没有事件时间可以用这个时间取代。
- processing-time:执行Operator算子的处理时间,本地系统时间,与机器无关。Flink默认使用处理时间。
状态就是一个本地变量,可以被业务逻辑访问。状态的存储涉及序列化反序列化问题,因为会分区间节点间传输。Flink提供了一整套状态管理机制,包括状态一致性、故障处理及高效存储和访问等。Flink中的状态包括:
- 算子状态:Operator State,处理步骤的状态。
- 键控状态:Keyed State,分组后Key的状态。每个键维护一个状态实例。每个分区保存自己分区所有的Key的状态数据。每个Key的数据只能访问自己Key对应的状态。状态包括:值状态、列表状态(一个Key的再分成多份数据便于下游重分区,但本来就按Key分份了其实不用再分了)、映射状态、聚合状态。
- 状态后端:State Backends。
状态先注册,一般状态不能跨任务(划分的子任务),状态和任务或算子绑定在一起,状态是存在在对应分区的,同一个分区存储一份状态,不同的key也是访问的一份状态数据,同一个子任务不同分区的状态是分开管理的。状态的存储数据格式一般是列表状态或联合列表状,就是每个分区将数据存储为几份,下游子任务可以按状态分区传递(岂不是每个分区又分了数据分区?)。
状态后端:State Backends,新来了数据,有状态的算子都要读取和更新状态。状态一般保存在分区内存中以保证低延迟的高效访问。状态的存储、访问及维护由一个可插入的组件完成,该组件称为状态后端。状态后端主要负责本地状态管理和将检查点状态写入远程存储(涉及序列化和反序列化)。状态后端包括:内存状态后端,MemoryStateBackend,存在TaskManager中,早期存在JVM堆内,后期版本存在JVM堆外内存,检查点存在JobManager中的内存中;FsStateBackend,文件系统状态后端,这种只是将检查点存储在文件系统上,本地状态还是存在TaskManager内存中;RocksDBStateBackend,序列化后存在RocksDB(会自动在内存和磁盘同时使用,不会出现OOM)中。一般使用FsStateBackend,状态数据特别大可用RocksDB。