有状态的流式处理(Stateful Functions)


传统批处理(batch layer)

传统批处理方法是持续收取数据,以时间作为划分多个批次的依据,再周期性地执行批次运算。但假设需要计算每小时出现事件转换的次数,如果事件转换跨越了所定义的时间划分,传统批处理会将中介运算结果带到下一个批次进行计算;除此之外,当出现接收到的事件顺序颠倒情况下,传统批处理仍会将中介状态带到下一批次的运算结果中,这种处理方式也不尽如人意。

流式处理(flow layer)

流式处理简单来讲即有一个无穷无尽的数据源在持续收取数据,以代码作为数据处理的基础逻辑,数据源的数据经过代码处理后产生出结果,然后输出,这就是流式处理的基本原理。

分布式流式处理

假设 Input Streams 有很多个使用者,每个使用者都有自己的 ID,如果计算每个使用者出现的次数,我们需要让同一个使用者的出现事件流到同一运算代码,这跟其他批次需要做 Group by 是同样的概念,所以跟 Stream 一样需要做分区,设定相应的 Key,然后让同样的 Key 流到同一个 Computation instance 做同样的运算。

有状态分布式流式处理

上述代码中定义了变数X,X 在数据处理过程中会进行读和写,在最后输出结果时,可以依据变数X 决定输出的内容,即状态X 会影响最终的输出结果。这个过程中,第一个重点是先进行了状态Co-partitioned key by,同样的 Key 都会流到 Computation instance,与使用者出现次数的原理相同,次数即所谓的状态,这个状态一定会跟同一个Key 的事件累积在同一个 Computation instance。类似于根据输入流的 Key 重新分区的状态,当分区进入 Stream 之后,这个 Stream 会累积起来的状态也变成 Copartiton 。

第二个重点是embeded local state backend。有状态分散式流式处理的引擎,状态可能会累积到非常大,当 Key 非常多时,状态可能就会超出单一节点的 Memory 的负荷量,这时候状态必须有状态后端去维护它;在这个状态后端在正常状况下,用 In-memory 维护即可。