Kafka流并发行为

时间:2018-02-01 19:48:27

标签: apache-kafka-streams

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

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

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

如果此代码由来自同一应用程序实例的多个流任务执行,将会发生什么情况?变量“已处理”如何,因为这也可以由多个线程更新?这需要在普通Java场景中进行某种同步。我很好奇,如果这是由Kafka流库处理。

谢谢!

1 个答案:

答案 0 :(得分:2)

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

有关此处的主题和任务的更多信息:Kafka Streams thread number

有关线程和任务以及共享状态的更多信息:Kafka stream processor thread safe?

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