这是我参与11月更文挑战的第2天,活动详情查看:2021最后一次更文挑战
前言
Kafka是一个非常优秀的开源框架,后来很多的消息中间件都是基于kafka的基础上,结合实际的业务场景做的一些改进,比如RocketMQ等,了解Kafka基本的实现原理对于开发的工作的十分必要,在kafka出现故障的时候知道怎么去解决。
消息的类型
消息的传递模式主要有两种, 消息传递模式:点对点传递模式、发布-订阅模式。
1.1 点对点传递模式
在点对点消息系统中,消息持久化到一个队列中。此时,将有一个或多个消费者消费队列中的数据。但是一条消息只能被消费一次。当一个消费者消费了队列中的某条数据之后,该条数据则从消息队列中删除。该模式即使有多个消费者同时消费数据,也能保证数据处理的顺序。
生产者发送一条消息到queue,只有一个消费者能收到。
1.2 发布订阅模式
在发布-订阅消息系统中,消息被持久化到一个topic中。与点对点消息系统不同的是,消费者可以订阅一个或多个topic,消费者可以消费该topic中所有的数据,同一条数据可以被多个消费者消费,数据被消费后不会立马删除。在发布-订阅消息系统中,消息的生产者称为发布者,消费者称为订阅者。
发布者发送到topic的消息,只有订阅了topic的订阅者才会收到消息。
大部分的消息系统选用发布-订阅模式。Kafka就是一种发布-订阅模式。
Kafka术语介绍
Broker
消息中间件处理节点,一个Kafka节点就是一个broker,一个或者多个Broker可以组成一个Kafka集群
Topic
Kafka根据topic对消息进行归类,发布到Kafka集群的每条消息都需要指定一个topic
Producer
消息生产者,向Broker发送消息的客户端
Consumer
消息消费者,从Broker读取消息的客户端
ConsumerGroup
每个Consumer属于一个特定的Consumer Group,一条消息可以被多个不同的Consumer Group消费,但是一个Consumer Group中只能有一个Consumer能够消费该消息
Partition
物理上的概念,一个topic可以分为多个partition,每个partition内部消息是有序的。
producer通过网络发送消息到Kafka集群,然后consumer来进行消费,如下图:
服务端(brokers)和客户端(producer、consumer)之间通信通过TCP协议来完成。
主题Topic和消息日志Log Topic是一个类别的名称,同类消息发送到同一个Topic下面。对于每一个Topic,下面可以有多个分区(Partition)日志文件:
Partition是一个有序的message序列,这些message按顺序添加到一个叫做commit log的文件中。每个partition中的消息都有一个唯一的编号,称之为offset,用来唯一标示某个分区中的message。
注意:每个partition,都对应一个commit log文件。一个partition中的message的offset都是唯一的,但是不同的partition中的message的offset可能是相同的。
Topic,Partition和Broker三者之间的关系?
- 一个topic,代表逻辑上的一个业务数据集。
- kafka集群,在配置的时间范围内,维护所有的由producer生成的消息,而不管这些消息有没有被消费。
- 每个consumer是基于自己在commit log中的消费进度(offset)来进行工作的。在kafka中,消费offset由consumer自己来维护,一般情况下我们按照顺序逐条消费commit log中的消息,当然我可以通过指定offset来重复消费某些消息,或者跳过某些消息。
注意:kafka中的consumer对集群的影响是非常小的,添加一个或者减少一个consumer,对于集群或者其他consumer来说,都是没有影响的,因为每个consumer维护各自的offset。所以说kafka集群是无状态的,性能不会因为consumer数量受太多影响。kafka还将很多关键信息记录在zookeeper里,保证自己的无状态,从而在水平扩容时非常方便。