Kafka-并非所有消费者都收到订阅的消息

时间:2019-04-08 15:10:01

标签: apache-kafka partition consumer

要使用Kafka一般发布消息,我将类名用作主题:

kafkaProducer.send(new ProducerRecord(object.getClass().getName(), new DomainObjectAdapter(object).toJsonString()));

消费者订阅他们感兴趣的课程:

    for(Object sub:_subscriptions)
        topics.add(sub.getClass().getName());
    _kafkaConsumer.subscribe(topics);

问题是,只有一个消费者曾经收到订阅的消息。我的理解是,kafka将为每个用户分配一个唯一的分区(如果有)。我目前只有2个订阅者,而我的kafka server.properties指定了4个分区。似乎所有使用者都从同一分区读取。由于这种明显的限制,Kafka可能不是服务巴士的理想选择。任何帮助将不胜感激!

Kafka消费者属性:

    properties.put("bootstrap.servers", _settings.getEndpoint());
    properties.put("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
    properties.put("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
    properties.put("enable.auto.commit", "false");
    properties.put("group.id", "TestGroup");
    properties.put("auto.offset.reset","earliest");

Kafka生产者属性:

    properties.put("bootstrap.servers",_settings.getEndpoint());
    properties.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");
    properties.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");

服务器属性(我从默认属性更改的唯一一件事):

num.partitions=4

注意:我还尝试了以下消费者设置:

    properties.put("bootstrap.servers", _settings.getEndpoint());
    properties.put("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
    properties.put("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
    properties.put("auto.commit.interval.ms","1000");
    properties.put("enable.auto.commit", "true");
    properties.put("group.id", "testGroup");
    properties.put("auto.offset.reset","latest");
    properties.put("partition.assignment.strategy", "org.apache.kafka.clients.consumer.RoundRobinAssignor");

2 个答案:

答案 0 :(得分:1)

默认情况下,Kafka使用RangeAssignor作为分区分配策略,具有以下特征:

  

范围分配器按主题工作。对于每个主题,我们   按数字顺序列出可用的分区,并按消费者列出   字典顺序。然后,我们将分区数除以   消费者总数确定要划分的分区数   分配给每个消费者。如果没有平均分配,则第一个   很少有消费者会有一个额外的分区。例如,假设   有两个使用者C0和C1,两个主题t0和t1,每个   主题有3个分区,导致分区t0p0,t0p1,t0p2,   t1p0,t1p1和t1p2。分配为:C0:[t0p0,t0p1,t1p0,   t1p1] C1:[t0p2,t1p2]

如果要为较少数量的分区分配更均匀的数据,则可以使用 通过设置partition.assignment.strategy

RoundRobinAssignor

答案 1 :(得分:1)

如果您的所有使用者都具有相同的使用者组(group.id属性),则该组中只有一个使用者将收到此消息。如果希望所有使用者都收到消息,则他们需要具有不同的group.id

要检查哪些使用者绑定到该主题的分区,可以使用以下命令

./bin/kafka-consumer-groups.sh --bootstrap-server yourhost:9092 --group testGroup --describe