Kafka的rebalance

背景

有一次看到kafka的rebalance,觉得挺有趣,于是自己动手实验一下

实验设计

设计一个包含3个分区的主题,分别验证消费者1,2,3,4个时分区和消费者的关系

实验步骤

  1. 创建一个包含3个分区的主题
//创建TopicName为topic-partition3的Topic并设置分区数为3以及副本数为1
@Bean
public NewTopic initialTopic() {
    return new NewTopic("topic-partition3",3, (short) 1 );
}
复制代码
  1. 一个生产者每1000ms往3个分区各生产一条数据
@Test
public void testProducer() throws InterruptedException {
    for (int i = 0; i < 5000; i++) {
        kafkaTemplate.send("topic-partition3", 0, null, "data package from partition0 [" + i + "]");
        kafkaTemplate.send("topic-partition3", 1, null, "data package from partition1 [" + i + "]");
        kafkaTemplate.send("topic-partition3", 2, null, "data package from partition2 [" + i + "]");
        //休眠1秒
        Thread.sleep(1000);
    }
}
复制代码
  1. 同一消费者组内逐条消费数据,每条耗时800ms
//声明consumerID为ypq-consumer, 消费组ypq-group, 为监听topicName为topic-partition3的Topic
@KafkaListener(id = "ypq-consumer", groupId = "ypq-group", topics = "topic-partition3")
public void listen(String msgData) throws InterruptedException {
    LOGGER.info("consume data : " + msgData);
    // 模拟耗时处理
    Thread.sleep(800);
}
复制代码
  1. 仅一个消费者时,C1打印ypq-group: partitions assigned: [topic-partition3-1, topic-partition3-2, topic-partition3-0]
  2. 两个消费者时,C1打印ypq-group: partitions assigned: [topic-partition3-1, topic-partition3-0], C2打印ypq-group: partitions assigned: [topic-partition3-2]
  3. 三个消费者,C1打印ypq-group: partitions assigned: [topic-partition3-0] ,C2打印ypq-group: partitions assigned: [topic-partition3-1], C3打印ypq-group: partitions assigned: [topic-partition3-2]
  4. 四个消费者时, C1-3打印不变, C4打印 ypq-group: partitions assigned: []

实验统计

消费者个数 P1 P2 P3
1 C1 C1 C1
2 C1 C1 C2
3 C1 C2 C3
4 C1 C2 C3

总结

  1. 消费者数大于分区数时,产生空闲的消费者,因为每个分区最多只能被一个消费者消费
  2. Kafka的rebalance默认策略是range,分区数对消费者数求余的余数会分配给靠前的消费者, 所以靠前消费者压力较大
  3. 同一topic下不同分区的数据不能保证有序, 同一分区下的数据保证有序
  4. 一个消费者如果要多线程消费, 需自行保证多线程消费的数据顺序
  5. 消费者还需考虑重复数据消费的场景

猜你喜欢

转载自juejin.im/post/7087495701642346526