文章目录

  • 1.状态定义
  • 1.1 有状态算子
  • 1.2 状态管理
  • 1.3状态分类
  • 2. 算子状态&按键分区状态
  • 2.1 算子状态
  • 2.2 按键分区状态(最常见)
  • 2.2.3 结构类型



分布式集群,分布式状态如何处理。

1.状态定义

每个任务进行中,可以只依赖当前的数据;但也可以依赖已经到来的数据(聚合操作),需要将已经到来的数据保存下来。这些用来计算输出结果的所有数据,或者由它们计算出的某个结果,叫做这个任务的状态。例如先下单,后支付事件模式。

1.1 有状态算子

无状态算子:比如map,flatmap,filter只需要独立观察当前数据
有状态算子:聚合算子、窗口算子。

1.2 状态管理

传统处理架构中,状态数据保存在数据库中国,实时流来说,达不到性能要求,解决方案是:将状态直接保存在内存中保证性能,并通过分布式扩展提高吞吐(单节点内存也会爆炸)。当前的状态就是当前子任务的本地变量。
主要问题:

  1. 状态的访问权限,不同的key可能在同一个分区,针对不同的key区分开
  2. 容错性,故障后恢复,状态只在内存中不够稳定,需要持久化保存做备份;从备份中恢复状态。
  3. 还应该考虑分布式应用的横向扩展性,数据量增大时,应响应对计算资源扩容,调大并行度,涉及到了状态的重组调整。

1.3状态分类

  • 托管状态、
    flink统一管理,直接调用接口;由flink的运行时来托管,配置容错机制后,状态进入自动持久化保存,发生故障时自动恢复。
    具体的使用:值状态、列表状态、映射状态、聚合状态。也可在富函数类中通过上下文自定义状态。
  • 原始状态(极端情况,托管状态无法处理)
    自定义,开辟一块内存自己管理,实现状态序列化和故障恢复

2. 算子状态&按键分区状态

2.1 算子状态

状态作用范围限定为当前算子任务实例,只对当前并行子任务实例有效,意味着对于一个并行子任务,占据了一个分区。所处理的所有数据都是同一个状态,别的分区访问不到。
算子状态可以作用在所有算子上,与本地变量类似

2.2 按键分区状态(最常见)

只能定义在keyedStream,根据输入流中国定义的Key来访问和维护,只能定义在按键分区流中,每一个子任务有不同的key,每个key都保存状态实例。

2.2.3 结构类型

值状态
列表状态
映射状态
规约状态
聚合状态