基本组成
生产者
org.apache.kafka.clients.producer.KafkaProducer
, 负责把消息发送到消息引擎的某个主题下的分区。
分区器
org.apache.kafka.clients.producer.Partitioner
,定位消息的分区。
序列化器
org.apache.kafka.common.serialization.Serializer
,序列化消息。
拦截器
org.apache.kafka.clients.producer.internals.ProducerInterceptors
,消息发送前会经过拦截器处理。
主题
是消息的分类,一般用来区分业务。
- 分区
是对主题的进一步划分,是消费者订阅消息的最小单元;订阅某个主题的消息,默认指定了一个分区。一个分区内的消息是有序的。 - 消费组
消费者所在的组,同一个组可以收到主题下的所有消息,组内的消费者处理主题下某个分区的消息。 - 消费者
处理发送到消息引擎的消息,组内的每个消费者(组内有多个消费者)只处理消费组接受到的部分消息。当然,如果组内只有一个消费者,会处理组内的所有消息。 - 节点
接受生产者和消费者的连接,记录和保存消息以及消息的消费状态。 - 集群
多个节点组成一个整体,共同对外提供服务。
它们的关系可以用下图来表示:
上图,是一个有Server1和Server2两个节点组成的Kafka集群。在这个集群中,分布着四个分区,Server1的两个分区P0和P3,Server2的两个分区P1和P2;有两个消费组,Consumer Group A和Consumer Group B;这两个消费组分别有消费者C1、C2和C3、C4、C5、C6。
默认情况下,一个主题的所有消息会通过规则分配到主题下的所有分区。如果规则是平均分配,那么P0一个消息,P1一个消息,P2一个消息,P3一个消息,如此反复循环。当然,也可以把所有的消息都发个一个分区,视规则而定。
一个分区的消息可以给多个消费组消费,但只能给每个消费组里的一个消费者消费。分区P0的消息可以给组A消费,也可以给组B消费;如果分区P0的消息给到组A的C1消费,就不能给到C2消费了;同理在组B中,P0的消息给到C3消费,就不能再给C4、C5、C6消费了。
下面是关于主题,分区,消费者和消费者的一个实验:
如上图,系统中有三个分区, 上面一排是组A的三个消费者,下面一排是组B的三个消费者,两个消费组订阅了同一个主题。在不指定分区的情况下,生产者推送的消息按照key的hash值分配给了不同的分区。由图可见,组A和组B都接收到了生产者推送的所有消息,但是每个组的消费者只拉取到一个分区的消息。