繁体   English   中英

Kafka-streams:为什么所有分区都分配给使用者组中的同一使用者?

Kafka-streams: Why do all partitions get assigned to the same consumer in the consumergroup?

提示:本站收集StackOverFlow近2千万问答,支持中英文搜索,鼠标放在语句上弹窗显示对应的参考中文或英文, 本站还提供   中文繁体   英文版本   中英对照 版本,有任何建议请联系yoyou2525@163.com。

背景

多台机器生成事件。 这些事件将发送到我们的Kafka集群,其中每台机器都有自己的主题(app.machine-events。machine -name )。 因为顺序对于每台计算机而言很重要,并且分区大小现在不是问题,所以所有主题都由一个分区组成。 因此,当前N个主题也意味着N个分区。

消费/处理应用程序利用kafka-streams,我们为它提供了StreamsConfig.APPLICATION_ID_CONFIG / "application.id" 'machine-event-processor',对于每个实例它都保持不变,这意味着它们被放入同一实例中卡夫卡的消费群体。 该使用者已订阅模式app.machine-events.* ,因为对于处理器,它处理的是哪个机器的事件都没有关系。 这已经通过./kafka-consumer-groups.sh --bootstrap-server localhost:9092 --describe --group machine-event-processor --members --verbose显示了一个与所有IP数量匹配的列表处理服务正在运行。

预期

给定20台计算机和5个处理器实例,我们希望每个处理器处理约4个分区(因此约有4个主题)。

其实

有一个处理器处理20个分区(因此有20个主题),而其他4个处理器则完全不执行任何操作/空闲。 杀死“幸运”处理器后,所有20个分区都重新平衡到另一个处理器,导致新处理器处理20个分区/主题,并使3个处理器空闲。

到目前为止我尝试过的

  • 检出partition.grouper 我觉得我不太了解,但是据我所知,仍然只有DefaultPartitioner选项,并且(根据文档)不必编写自定义选项,因为此设置可以正常工作。 它确实提到了分区是基于分区键(对于我们来说都是0,因为每个主题只有一个分区)加入到任务中,但是我无法完全理解这一部分。
  • 供使用者使用的RoundRobinAssignor: settings.put(StreamsConfig.consumerPrefix(ConsumerConfig.PARTITION_ASSIGNMENT_STRATEGY_CONFIG), new RoundRobinAssignor().getClass.getName) (尝试了多个值,因为似乎没有什么变化。)
  • 查看其他配置属性 ,以查看是否遗漏了一些东西:我认为没有。

代码,简化

val streamConfig = new Properties
// {producer.metadata.max.age.ms=5000, consumer.metadata.max.age.ms=5000, default.key.serde=org.apache.kafka.common.serialization.Serdes$StringSerde, consumer.partition.assignment.strategy=org.apache.kafka.clients.consumer.RoundRobinAssignor, bootstrap.servers=kafka:9092, application.id=machine-event-processor, default.value.serde=org.apache.kafka.common.serialization.Serdes$ByteArraySerde}
val builder: StreamsBuilder = new StreamsBuilder
val topicStream: KStream[String, Array[Byte]] = builder.stream(Pattern.compile("app.machine-events.*"))
topicStream.process(new MessageProcessorSupplier(context)) // The event is delegated to a processor, doing the actual processing logic
val eventStreams = new KafkaStreams(builder.build(), streamConfig)
eventStreams.start()

笔记

  • 使用Kafka-streams 2.0.0:

    <dependency> <groupId>org.apache.kafka</groupId> <artifactId>kafka-streams</artifactId> <version>2.0.0</version> </dependency>

  • Kafka正在使用wurstmeister/kafka:2.11-2.0.0版本在容器内运行。 docker-stack.yml服务:

kafka: image: wurstmeister/kafka:2.11-2.0.0 ports: - target: 9094 published: 9094 protocol: tcp mode: host volumes: - /var/run/docker.sock:/var/run/docker.sock healthcheck: test: ["CMD-SHELL", "$$(netstat -ltn | grep -q 9092)"] interval: 15s timeout: 10s retries: 5 environment: HOSTNAME_COMMAND: "docker info | grep ^Name: | cut -d' ' -f 2" KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181 KAFKA_ZOOKEEPER_CONNECTION_TIMEOUT_MS: 36000 KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: INSIDE:PLAINTEXT,OUTSIDE:PLAINTEXT KAFKA_ADVERTISED_LISTENERS: INSIDE://:9092,OUTSIDE://_{HOSTNAME_COMMAND}:9094 KAFKA_LISTENERS: INSIDE://:9092,OUTSIDE://:9094 KAFKA_INTER_BROKER_LISTENER_NAME: INSIDE KAFKA_DEFAULT_REPLICATION_FACTOR: 2 deploy: replicas: 2 restart_policy: condition: on-failure delay: 5s max_attempts: 3 window: 120s

  • Kafka是在双节点设置中设置的,形成一个集群。 通过docker环境变量,我们将复制因子设置为2 ,因此每个分区应该在每个节点上都有一个复制。

我找到并检查过的相关主题/问题/讨论

如果有人遇到类似问题,或者能够指出我可能非常愚蠢的错误,请赐教!

1 个回复

对于将来遇到此问题的读者,解决方案是不使用每个都有1个分区的N个主题,而使用带有N个分区的1个主题。 即使有120个分区和400多个计算机/事件源,也将多个事件类型放入同一个分区,但这不会影响事件的顺序。

实现是将记录键设置为计算机名称,并让底层逻辑负责将哪个值分配给哪个分区。 由于我们现在有一个消费者组,其中有X个消费者订阅了该主题,因此分区在消费者上平均分配,每个分区有120 / X个分区。

正如Matthias所建议的那样,Confluent的其他乐于助人的人在Devoxx Belgium 2018上进一步证实了这一点。谢谢!

小费

使用wurstmeister / kafka docker映像时,请考虑使用environment属性:

KAFKA_CREATE_TOPICS:“ app.machine-events:120:2”

含义

主题名称:数的-分区:复制因子

1 Kafka-Streams 消费者的 RecordInterceptor

我正在寻找用于事件的 Kafka 流。 我尝试为 Kakfa-Streams 添加一个拦截器(为消费者)。 我添加了一个 RecordInterceptor,如下所示: 但是在启动过程中出现错误: 如果我添加一个实现的拦截器,它工作正常 org.apache.kafka.clients. ...

5 Spring Kafka获得分配的分区

我知道我可以从哪个分区记录中找到,但我想知道有什么方法可以动态地获取在特定时刻为消费者分配的分区吗? 也许我需要实现一些侦听器来检测并跟进分区分配信息? 我使用spring-kafka 1.3.2与ConcurrentKafkaListenerContainerFactory和@Kafk ...

6 如何限制kafka-streams中的rocksdb内存使用量

我正在使用kafka-streams,并且off heap内存使用量增长到了机器的物理极限。 但是,当在docker中运行kafka-streams时,内存使用量会超过容器的限制,因此容器会被OOM杀死。 我的假设是rocksdb正在分配关闭堆空间。 -Xmx可以用来限制堆的使用,但是 ...

7 Kafka-Streams拓扑,根据条件获取价值

我有两个不同的对象是: 和第二个对象 如您所见,两个对象完全不同。 两个对象都将放在自己的主题中。 根据某些标准,Obj1需要Obj2。 为了获得Obj2,我用一个与obj1.xNumber匹配的键将其放在他的主题中。 因此,在我的流拓扑中,我想查看两个对象并执行以下操作: 我怎样才能 ...

8 当另一个使用者加入同一组时,分配给该使用者的所有已暂停分区都将被吊销

我有一个用户订阅了一个主题,它正在轮询3个分区。 由于我的特定用例,此使用者调用了pause(TopicPartition)方法,因此所有分区都将设置为暂停状态。 无论如何,它都会继续轮询以发送心跳。 然后,第二个消费者加入同一组。 协调器重新平衡分区。 可以预期这两个使用者之间的3个分区是平衡的, ...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2022 STACKOOM.COM