Kafka流处理器线程安全吗?

时间:2017-11-05 07:43:39

标签: java multithreading apache-kafka-streams

我知道此问题在此之前被问过:Kafka Streaming Concurrency?

但这对我来说很奇怪。根据文档(或者我可能缺少某些东西),每个分区都有一个任务,意味着不同的处理器实例,每个任务都由不同的线程执行。但是当我测试它时,我看到不同的线程可以获得不同的处理器实例。因此,如果您想在处理器中保持任何内存状态(老式方式),您必须锁定?

示例代码:

public class SomeProcessor extends AbstractProcessor<String, JsonObject> {

   private final String ID = UUID.randomUUID().toString();

   @Override
   public void process(String key, JsonObject value) {
     System.out.println("Thread id: " + Thread.currentThread().getId() +" ID: " + ID);

输出:

主题ID:88 ID:26b11094-a094-404b-b610-88b38cc9d1ef

主题ID:88 ID:c667e669-9023-494b-9345-236777e9dfda

主题ID:88 ID:c667e669-9023-494b-9345-236777e9dfda

主题ID:90 ID:0a43ecb0-26f2-440d-88e2-87e0c9cc4927

主题ID:90 ID:c667e669-9023-494b-9345-236777e9dfda

主题ID:90 ID:c667e669-9023-494b-9345-236777e9dfda

有没有办法按实例强制执行线程?

1 个答案:

答案 0 :(得分:2)

每个实例的线程数是一个配置参数(num.stream.threads,默认值为1)。因此,如果您启动单个KafkaStreams实例,则会获得num.stream.threads个帖子。

任务以并行单位(基于您的输入主题分区)拆分工作,并将分配给线程。因此,如果您有多个任务和一个线程,则所有任务都将分配给该线程。如果你有两个线程(所有KafkaStreams个实例的总和),每个线程执行大约50%的任务。

  

注意:因为Kafka Streams应用程序本质上是分布式的,所以如果您运行具有多个线程的单个KafkaStreams实例,或者多个KafkaStreams实例,每个实例都有一个线程,则没有区别。任务将分布在应用程序的所有可用线程上。

如果您想在任务之间共享任何数据结构,并且您有多个线程,则您有责任同步对此数据结构的访问。请注意,任务到线程分配可以在运行时更改,因此,必须同步所有访问。 但是,不建议使用此模式,因为它限制了可伸缩性。您应该设计没有共享数据结构的程序!这样做的主要原因是,您的程序通常分布在多台计算机上,因此,不同的KafkaStreams实例无法访问共享数据结构。共享数据结构只能在单个JVM中工作,但使用单个JVM可以防止应用程序出现水平扩展。