kafka采用分区(Partition)的方式,使得消费者能够做到并行消费,从而大大提高了自己的吞吐能力。同时为了实现高可用,每个分区又有若干份副本(Replica),这样在某个broker挂掉的情况下,数据不会丢失。
大多数消息系统,同一个topic下的消息,存储在一个队列。分区的概念就是把这个队列划分为若干个小队列,每一个小队列就是一个分区,如下图:
这样做的好处是什么呢?无分区时,一个topic只有一个消费者在消费这个消息队列。采用分区后,如果有两个分区,最多两个消费者同时消费,消费的速度肯定会更快。如果觉得不够快,可以加到四个分区,让四个消费者并行消费。分区的设计大大的提升了kafka的吞吐量!!
结合下图理解Partition
说明:
1.一个partition只能被同组的一个consumer消费;
2.同组里的一个consumer可以消费多个partition;
3.消费效率最高的情况是partition和consumer数量相同。这样确保每个consumer专职负责一个partition。
4.consumer数量不能大于partition数量。由于第一点的限制,当consumer多于partition时,就会有consumer闲置。
5.consumer group可以认为是一个订阅者的集群,其中的每个consumer负责自己所消费的分区.
副本(Replica)
提到副本,肯定就会想到正本。副本是正本的拷贝。在kafka中,正本和副本都称之为副本(Repalica),但存在leader和follower之分。活跃的称之为leader,其他的是follower。
每个分区的数据都会有多份副本,以此来保证Kafka的高可用。
topic下会划分多个partition,每个partition都有自己的replica,其中只有一个是leader replica,其余的是follower replica。
消息进来的时候会先存入leader replica,然后从leader replica复制到follower replica.只有复制全部完成时,consumer才可以消费此条消息.这是为了确保意外发生时,数据可以恢复.聪的消息也是聪lead replica读取的.
由此可见,leader replica做了大量的工作,所以如果不同的partition的lead replica在kafka集群的broker上分布不均匀,就会造成负载不均衡.
kafka通过轮询算法保证leader replica是均匀分布在多个broker上。
通过之前的学习,我们知道topic下划分了多个partition,消息的生产和消费最终都是发生在partition之上。下图是一个三个partition的topic的读写示意。
消息在写入的时候,采用round-robin算法,轮询往每个partition写入.而在消费者端,每个consumer都维护了一个offset值,指向的是它所消费到的消息坐标.在A消费组中的三个consumer,他们分别独立消费不同的三个partition.每个consumer维护了自己的offset.在消费b组中,可以看到两个group是并行消费整个topic,同一个消息会被不同的group消费到.
此处有如下知识点:
1、每个partition都是有序的不可变的。
2、Kafka可以保证partition的消费顺序,但不能保证topic消费顺序。
3、无论消费与否,保留周期默认两天(可配置)。
4、每个consumer维护的唯一元数据是offset,代表消费的位置,一般线性向后移动。
5、consumer也可以重置offset到之前的位置,可以以任何顺序消费,不一定线性后移。