Kafka 流并发行为

Kafka streams concurrency behavior

如果我的 kafka streams 应用程序中有一个共享变量,并且在处理代码中被多个线程更新,它是如何处理的?我是否必须使该共享变量线程安全,或者 Kafka 流库如何处理?在文档的某个地方,我读到当 运行 Kafka 流应用程序时不需要在线程之间进行协调。例如,这是一个伪代码:

KStream<byte[], byte[]> input = ...;
int counter = 0;

KStream<byte[], byte[]>[] processed = input.map(
    (k, v) -> {
      ....
      ....
      //update counter by multiple threads.
);

如果这段代码被来自同一个应用程序实例的多个流任务执行,会发生什么情况?变量 "processed" 怎么样,因为它也可以由多个线程更新?这需要在正常 Java 场景中进行某种同步。我很好奇这是否由 Kafka 流库处理。

谢谢!

这取决于您为执行任务配置的线程数。如果您有一个线程执行所有任务,那么您不必使该共享变量线程安全。但是,如果您有多个线程,则需要使其成为线程安全的,因为应用程序实例中的任务将分布在多个线程中。您的 Kafka Streams 应用程序只是一个 运行 JVM,您从 main() 开始。 Kafka Streams 框架根据您指定的线程数编排处理。但它只是一个常规的 Java 运行时,并发访问仍然是并发访问。

更多关于线程和任务的信息:

关于线程和任务以及共享状态的更多信息:

显然,一般来说,您在代码示例中显示的模式是您可能希望避免的模式,除非它实际上只是在计算本地应用程序的某些内容。在您有 运行 个多个应用程序实例的生产应用程序中,如果应用程序实例启动或关闭,任务会重新分配,因此您的共享变量可能不会有用。这就是 Kafka Streams 存储机制如此有用的原因:你的状态随着任务而移动。