KafkaStreams处理器分区重新分配行为

时间:2017-11-15 11:40:01

标签: apache-kafka-streams

假设我有一个基本的KafkaStreams应用程序,其中包含一个主题(具有多个分区)和一个处理消息的处理器类型,如下所示:

    builder.stream(topic)
           .process(() -> new MyProcessor());

是否会出现以下情况?对于MyProcessor的特定实例,例如 M (即通过调用处理器供应商获得的特定java对象),以及对于该主题的特定分区,例如 P

  1. 在某个时间t 1 M 接收来自 P 的消息
  2. 稍后t 2 P M 撤销,因此 M 不接收来自 P 了(例如,因为启动了额外的工作人员来处理 P
  3. 稍后,t 3 M 再次从 P
  4. 接收消息

    我检查了documentation关于流任务如何与Kafka主题分区相关但我没有找到有关如何与构造和删除处理器实例和/或(取消)主题分区相关的详细信息重新平衡发生时对现有处理器的影响。

1 个答案:

答案 0 :(得分:3)

在Kafka Streams,"处理单位"被称为流任务

任务可以是有状态的和/或无状态的。当重新平衡事件发生时,在应用程序的一个实例(例如,M)上运行的任务可能会被移动到应用程序的另一个实例。

主题分区和流任务之间存在1-1映射,这保证了一个且只有一个任务将处理来自特定分区的数据。例如,如果任务3负责从分区P读取和处理,那么当任务3从实例M移动到另一个实例M'时,则M将停止阅读P(因为它不再运行任务3),M'(现在任务3运行)将继续/继续处理P

  
      
  1. 在某个时间t1,M从P
  2. 接收消息   

让我们说负责处理主题分区P的流任务称为task(P)。在时间t1,M恰好是运行task(P)的应用实例。这就是上面#1点的情况。

  
      
  1. 在稍后的时间点t2,P从M撤销,因此M不再接收来自P的消息(例如,因为启动了一个处理P的额外工作人员)
  2.   

这里,应用程序的另一个实例(您将此实例称为"额外的工作者")负责运行task(P)。此处,task(P)会自动从原始应用实例M迁移到新实例M'。由task(P)管理的任何状态(例如,当任务正在执行诸如连接或聚合的有状态操作时)当然将与任务一起迁移。迁移task(P)后,读取和处理主题分区P的责任也将从应用实例M移至M'

或许并没有过多考虑"哪个应用实例正在处理主题分区P?"相反,特定分区始终由特定流任务处理,并且流任务可以跨应用实例移动。 (当然,Kafka的Streams API可以防止不必要的任务迁移,以确保您的应用程序处理保持高效。)

  
      
  1. 稍后,t3,M再次从P
  2. 接收消息   

这意味着,在时间t3,由于另一个重新平衡事件,M被再次分配了任务task(P) - 可能是因为另一个应用实例M'已被删除,或发生了需要任务迁移的其他事情。