流处理中的状态模型

流处理中的状态无处不在,任何一个复杂的计算都需要在中途产生状态.比如一个聚合算子,会计算事件的某个数之和,这个算子每次收到新事件就会更新.那么更新的就是状态

对于状态,在之前的批处理系统中,数据会被分为多个小的批次数据.然后在每个批次数据计算后,讲状态存储在某个外部系统(诸如数据库),而对于持续的流计算中,可能需要每次处理数据都更新状态,这时候是可以利用外部系统来管理流处理的状态,不过也会因此引入额外的延迟.而且需要开发人员注意,由于状态是在不断地变化的,需要注意状态的大小,一般来说,算子通常只会保存一个小状态,比如一个数量值,一个累加值.一个窗口缓冲等.

总结一下,对于状态管理,存在着一些难点和挑战

1.对于状态管理,需要高效的管理状态并确保其不受更新的影响

2.且支持根据事件的键值分区,并独立维护每一个区域的状态.

3,并需要在故障出现后可以恢复状态,可以保证结果的正确.

对于上面三点,状态保存我们后续讲解,分区本身就是支持的.而状态的保存和恢复是确保状态正确性的重点.

一个流处理最终会形成一个Dataflow图,在实际执行时,就是很多并行的子算子任务,每个任务有可能出现故障,如何处理这些故障,在不影响最终结果的正确性地前提下继续运行流式作业呢?

而面对不同的处理需求,也存在不同的结果保障机制,那么我们接下来就讲解下结果保障及对应的实现结果.

最简单的保存语义是最多一次

任务发生故障的时候,如果不恢复丢失的状态,也不重放丢失的事件,那么就是每个事件最多被处理一次.这个语义下没有保障,因为被系统丢掉所有的事件都可以满足其结果.如果只是希望降低延迟,这种保障其实可以接受.

至少一次,其能保证不丢失事件,如果正确性只是依赖于信息的完整度,那么可以接受,最坏的结果也是多几次定位到事件,但是如果有着计算某个事件在输入流中出现的次数,那么这个会返回错误的结果.

而为了能确保至少一次,那么需要在源头有着重放机制,无论是上流数据源可以重放,还是算子中的缓冲区,只要可以重放,是可以满足至少一次的.

精准一次,是最严格,最难以保障的,因为要确保一个事件对应的更新只能有一次.其可以保证应用总能提供正确结果.精准一次的实现也需要数据重放机制,而且在故障恢复后,需要知道自己更新到哪个事件的状态了,Flink给出的实现是检查点机制,这个我们会将.

而对于上面的保存语义的实现,由于整个系统是包含上游数据源和下游的数据输出的,故整体的语义往往是水桶,取决于最弱的组件.

而且不同语义的选择,往往要根据实际业务需求来判断.

发表评论

邮箱地址不会被公开。 必填项已用*标注