我知道此问题在此之前被问过: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
有没有办法按实例强制执行线程?
答案 0 :(得分:2)
每个实例的线程数是一个配置参数(num.stream.threads
,默认值为1
)。因此,如果您启动单个KafkaStreams
实例,则会获得num.stream.threads
个帖子。
任务以并行单位(基于您的输入主题分区)拆分工作,并将分配给线程。因此,如果您有多个任务和一个线程,则所有任务都将分配给该线程。如果你有两个线程(所有KafkaStreams
个实例的总和),每个线程执行大约50%的任务。
注意:因为Kafka Streams应用程序本质上是分布式的,所以如果您运行具有多个线程的单个
KafkaStreams
实例,或者多个KafkaStreams
实例,每个实例都有一个线程,则没有区别。任务将分布在应用程序的所有可用线程上。
如果您想在任务之间共享任何数据结构,并且您有多个线程,则您有责任同步对此数据结构的访问。请注意,任务到线程分配可以在运行时更改,因此,必须同步所有访问。 但是,不建议使用此模式,因为它限制了可伸缩性。您应该设计没有共享数据结构的程序!这样做的主要原因是,您的程序通常分布在多台计算机上,因此,不同的KafkaStreams
实例无法访问共享数据结构。共享数据结构只能在单个JVM中工作,但使用单个JVM可以防止应用程序出现水平扩展。