2025-7-9
kafka是一个分布式、高吞吐量、高扩展性的消息队列系统。kafka最初是由Linkedin公司开发的,后来在2010年贡献给了Apache基金会,成为了一个开源项目。
1. 概念一览:
Producer (生产者)
Topic (主题)
Partition (分区)
Replica (副本)
Broker (实例/节点)
Consumer Group (消费者组) 和 Consumer (消费者)
2. 架构与设计
一般的来说,一个Kafka集群包含一个或多个的Producer,一个或多个的Broker,一个或多个的ConsumerGroup,和一个Zookeeper集群。Kafka通过Zookeeper^1 管理集群配置,管理集群在运行过程中负载均衡、故障转移和恢复等。Producer通过向Topic 使用 push(推送)的方式将消息发布到Broker,Consumer使用Pull(拉取)的方式从Broker获取消息,两者都是主动操作的。
在对Topic和Partition的设计中,把Topic分成一个或者多个Partition,每个Partition在物理磁盘上对应一个文件夹,该文件夹下存储这个Partition的所有消息和索引文件。当我们创建一个Topic时,同时可以指定分区数据,数目越多,吞吐量越大,但是消耗的资源也越多,当我们向Kafka发送消息时,会均衡的将消息分散存储在不同的分区中。在存储的过程中,每条消息都是被顺序写到磁盘上的。(顺序写磁盘的时候比随机写内存的效率还高,这也是Kafka快的一个原因之一)。
对于传统的MQ而言,一般经过消费后的消息都会被删除,而Kafka不会直接删除,通过记录一个消费者消费消息的offset(偏移量)作为标记,可以允许消费者自己设置这个offset,从而重复消费一些消息。Kafka提供了两种策略来删除消息:一是基于时间,二是基于Partition文件的大小,可以通过配置来决定用那种方式。
传统的消息队列有两种传播消息的方式,一种是单播,类似队列的方式,一个消息只被消费一次,消费过了,其他消费者就不能消费;另一种是多播,类似发布-订阅的模式,一个消息可以被多个消费者同时消费。Kafka通过消费者组的方式来实现这两种方式,Kafka 会将主题的分区分配给消费者分组中的各个消费者实例,每个分区只能被一个消费者实例消费。所以对于设置了多分区的Topic来说,分区的个数和消费者的个数应该是一样的,一个消费者消费一个分区,这样每个消费者就成了单播形式,类似队列的消费形式。所以说,一个消费者组里边的消费者不能多于Topic的分区数,一旦多于,多出来的消费者就不能消费到消息。这样可以确保消息的顺序性,并且避免了多个消费者同时消费同一个分区的消息导致的重复消费问题。另外,不同的消费者组可以同时消费一个消息,这样就实现了多播,类似发布-订阅的模式。我们可以设置每个组中一个消费者的方式来实现发布-订阅的模式。当我们有多个程序都要对消息进行处理时,我们就可以把他们设置到不同的消费者组中,来实现不同的功能。
为了保证数据的可靠性,可以为一个Brocker创建多个副本,多个副本只能有一个提供读写操作,具有读写能力的副本称为Leader副本,作为备份的副本称为Flower副本。
在kafka4.x已经彻底移除了对zookeeper的依赖,同时最低Java支持版本由Java8提高为Java11,新特性请查看Kafka4.0.0官方更新文档