KAFKA分区、生产者、消费者之间的关系
大家都知道,Kafka生产者发送消息到主题,消费者订阅主题消费消息。而主题下边是分区,消息是存储在分区中,所以事实上是生产者发送消息到分区,消费者从分区读取消息。
所以,生产者发送消息到哪个分区?消费者又从哪个分区读取消息呢?
kafka主题的分区数可以自己设置,如果创建主题的时候没有指定分区数量,就会使用默认的server.properties中的设置。
- 生产者与分区的关系:
默认的分区策略:
如果发送消息的时候指定了分区,则消息发送到指定分区;
如果没有指定分区,但是消息的key不为空,则基于key的哈希值来选择一个分区;
如果既没有指定分区,且消息的key为空,则用轮询的方式选择一个分区。
- 消费者与分区的关系:
消费者以组的名义订阅主题,主题有多个分区,消费者组有多个实例,这些实例和分区是什么关系?
同一时刻,一条消息只能被组中一个消费者实例消费。
消费者组订阅这个主题就表示主题中的所有分区都会被消费者组中的实例消费到。换句话说,就是主题的每隔分区只能被一个消费者实例消费,不可能出现两个消费者负责两个分区
所以,
如果分区数大于或者等于消费者实例数,那么无非就是一个消费者负责多个分区;
最理想的情况就是分区数等于消费者实例数,一个消费者负责一个分区,
如果消费者实例的数量大于分区数,那么按照默认的策略,有些消费者是多余的,会一直接收不到消息而处于空闲状态。
那么,会不会存在多个消费者负责同一个分区的数据呢?
Kafka在设计的时候就是保证了分区下消息的顺序,也就是消息在分区中的顺序是怎样,那么消费者在消费的时候看的顺序就是怎样。要做到这一点就需要保证消息是由消费者主动拉取的(pull),还要保证一个分区只能由一个消费者负责。
假如,一个分区有两个消费者消费,也就是两个消费者同时读取分区的数据,由于消费者可以自己控制读取消息的offset,就有可能C1读到1,C2读到2,C2还没有处理完,C1已经读到3了,就会造成很大的浪费,这就相当于多线程消费一个消息,会造成消息的重复,且不能保证消息的顺序,就类似于主动推送(PUSH)。