Flink 中的事件处理顺序和恢复

Order of events processing in Flink and recovery

研究Flink一个多星期了。我们正在消费来自 Kafka 的事件,我们希望属于特定对象 ID 的事件需要按照事件时间的顺序进行处理。到目前为止,我的研究告诉我,我应该使用 keyby 和 timeWindows,我的理解正确吗?

另一个问题,当一个taskmanager宕机时,只有那些属于那个taskmanager的事件才会被停止处理,直到任务管理器出现?检查点机制是否知道未处理的事件,它将如何向 Kafka 请求有关这些事件的信息?

下面用例的问题

在 CallCenter 中,座席将接听电话并进入不同的状态。对于代理的每个动作,比如登录、空闲、忙碌等,我们通过 Kafka 获取该动作的代理事件作为状态。要求是我们必须按代理顺序处理事件,我们不能在登录事件之前处理代理空闲事件。我们需要按顺序处理这些,同时我们需要横向扩展。

在并行进程的Flink集群中,我们不应该在不同的partitions/TaskSlots处理agent信息,而agent的状态不好。我的问题是 keyBy agentId 会将流分成子流并一直在指定的分区中处理它们,这样可以保持事件处理的顺序。

此外,另一个问题是如果有一个 exception/task 管理器正在为处理特定代理数据的分区关闭,Flink 如何知道在恢复后只请求那些代理事件。

您需要使用 keyBy(objectId) 按对象 ID 对流进行分区。

如果您必须按事件时间对流进行排序,您有几个选择。您可以使用 windows 创建您在 ProcessWindowFunction 中排序(逐批)的事件批次,或者您可以使用 KeyedProcessFunction 创建连续的有序流。 Here's an example.

Flink 中的检查点是全局的。它们包括 Kafka 中的偏移量以及分布式集群中的所有状态,这些状态是由于摄入了这些偏移量的输入而产生的。恢复涉及重启集群、恢复集群的状态、将 Kafka 消费者倒回到检查点中记录的偏移量,以及从该点重播事件。请注意,如果您的接收器不是事务性的,这可能会导致写入重复的结果。

更新:

如果每个键的所有数据都只在一个 Kafka 分区中,并且如果您的数据已经在 Kafka 中排序(不是全局排序,而是在每个键中排序),那么 Flink 将保留该顺序,即使如果你做一个keyBy。这是可行的,因为任何给定的 Kafka 分区仅由 Flink Kafka 源的一个实例使用。

至于第二个问题,只有一个任务管理器宕机没有关系。所有任务管理器都将重新启动,它们将从存储在最近检查点中的偏移量全部倒带并恢复处理。检查点是全局的,跨越整个集群——不支持部分恢复。