状态编程(算子状态 Operator State)

目录

 状态编程    

  算子状态 Operator State

1.基本概念和特点

2.状态类型


 状态编程    

  算子状态 Operator State

  除了按键分区状态(Keyed State)外,另一类受控状态是算子状态(Operator State)。算子状态在某种意义上可以被视为更底层的状态类型,因为它仅对当前算子的并行任务有效,而不需要考虑不同键值的隔离。与按键分区状态相比,算子状态的功能较为有限,应用场景也较少。算子状态的调用方法与按键分区状态有所不同,这主要表现在对状态的访问和更新方面。

        在实际应用中,选择使用按键分区状态还是算子状态取决于具体的需求和场景。按键分区状态更适合处理与特定键值相关联的数据,并提供了丰富的功能和操作,例如过滤、分组、聚合等。而算子状态适用于只需要在当前算子的并行任务中共享状态的情况,其功能和应用场景相对较少。

        在实现状态管理时,需要考虑状态的粒度和隔离性。按键分区状态适用于处理与特定键值相关联的数据,它提供了更好的隔离性和数据一致性。而算子状态适用于在当前算子的并行任务中共享状态的情况,它不需要考虑不同键值的隔离问题。

1.基本概念和特点

        算子状态(Operator State)是定义在算子并行实例上的状态,其作用范围仅限于当前的算子任务。与数据的键值无关,因此不同键的数据只要被分发到同一个并行子任务,就会访问到同一个算子状态。

        相对而言,算子状态的实际应用场景不如按键分区状态(Keyed State)丰富。一般来说,算子状态主要用于与外部系统连接的Source或Sink等算子上,或者在没有定义键的场景中使用。

        重要的是,当算子的并行度发生变化时,算子状态也支持在并行的算子任务实例之间进行重组分配。根据状态类型的不同,重组分配的方案也会有所差异。

        综上所述,算子状态是一种在特定算子上定义的状态,其作用范围仅限于该算子任务,且与数据的键值无关。相比之下,按键分区状态提供了更丰富的功能和操作,适用于处理与特定键值相关联的数据。在实际应用中,需要根据具体需求和场景选择合适的状态类型来管理数据和共享状态。

2.状态类型

算子状态也支持不同的结构类型,主要有三种:ListState、UnionListState 和 BroadcastState。

  1. 列表状态(ListState)

与按键分区状态中的ListState一样,将状态表示为一组数据的列表。但在算子状态的上下文中,不会按不同的键值分别处理状态。因此,每个并行子任务上只会保留一个“列表”,即当前并行子任务上的所有状态项的集合。列表中的状态项是完全独立的,可以被重新分配。

当算子并行度发生变化时,算子的列表状态中的所有元素项会被统一收集起来,相当于把多个分区的列表合并成了一个“大列表”,然后再均匀地分配给所有并行任务。这种“均匀分配”的具体方法是通过逐一“发牌”的方式将状态项平均分配,被称为“平均分割重组”(even-split redistribution)。

  1. 联合列表状态(UnionListState)

与ListState类似,联合列表状态也会将状态表示为一个列表。与常规列表状态的主要区别在于算子并行度变化时状态的分配方式不同。

UnionListState的重点在于“联合”(union)。在并行度调整时,常规列表状态使用轮询方式分配状态项,而联合列表状态的算子会直接广播状态的完整列表。这种方式使得并行度调整后的并行子任务获取到联合后的完整“大列表”,并自行选择要使用的状态项和要丢弃的状态项。这种分配方式也被称为“联合重组”(union redistribution)。如果列表中状态项数量过多,考虑到资源和效率,一般不建议使用联合重组的方式。

  1. 广播状态(BroadcastState)

有时我们希望算子的所有并行子任务都保持同一份“全局”状态,用于统一的配置和规则设定。这时,所有分区的所有数据都会访问到同一个状态,就像状态被“广播”到所有分区一样。这种特殊的算子状态被称为广播状态(BroadcastState)。

由于广播状态在每个并行子任务上的实例都是一样的,所以在并行度调整时比较简单。只需将状态复制一份到新的并行任务即可实现扩展。而对于并行度缩小的情况,可以将多余的并行子任务连同状态直接砍掉,因为状态是复制出来的,并不会丢失。

在底层,广播状态是以类似映射结构(map)的键值对(key-value)来保存的,必须基于一个“广播流”(BroadcastStream)来创建。

你可能感兴趣的:(flink知识点,算法,flink,大数据)