1.为什么要使用消息队列?
-
解耦
-
不同的模块可以将消息发送到消息队列中,接收方可以独立地消费消息,实现了模块之间的解耦。
-
-
异步
-
将消息放入消息队列中,可以异步地处理这些操作,不影响主流程的执行
-
-
削峰填谷
-
使用消息队列作为缓冲区,将请求放入消息队列中,然后在系统负载低的时候进行处理
-
2.消息队列的实现
-
kafka、activeMQ、RabbitMQ和RocketMQ等
-
kafka的优势在于吞吐量高,易于使用和部署
3.kafka吞吐量高的原因
-
消息发送方面
-
批量发送:Kafka 通过将多个消息打包成一个批次,减少了网络传输和磁盘写入的次数
-
消息压缩:支持对消息进行压缩,减少网络传输的数据量。
-
并行发送:通过将数据分布在不同的分区(Partitions)中,生产者可以并行发送消息
-
-
消息存储方面
-
零拷贝技术:Kafka 使用零拷贝技术来避免了数据的拷贝操作,降低了内存和 CPU 的使用率
-
页缓存:Kafka 将其数据存储在磁盘中,但在访问数据时,它会先将数据加载到操作系统的页缓存中,并在页缓存中保留一份副本,从而实现快速的数据访问。
-
-
消息消费
-
并行消费:不同的消费者可以独立地消费不同的分区,实现消费的并行处理。
-
批量拉取:Kafka支持批量拉取消息,可以一次性拉取多个消息进行消费。减少网络消耗,提升性能
-
4.Kafka的架构
-
主要由 Producer(生产者)、broker(Kafka集群)和 consumer(消费者) 组成。生产者负责将消息发布到Kafka集群中的一个或多个主题(Topic) 。消费者负责从Kafka集群中的一个或多个主题消费消息
-
-
一个broker可以有多个topic,每个Topic包含一个或多个分区(Partition) ,Leader Broker 是分区的主副本 ,只有 Leader Broker 才能处理生产者和消费者的请求 ,Follower Broker 只是 Leader Broker 的备份,用于提供数据的冗余备份和容错能力
5.Kafka 的重平衡机制
-
Kafka 的重平衡机制
-
在消费者组中新增或删除消费者时,Kafka 集群会重新分配主题分区给各个消费者,以保证每个消费者消费的分区数量尽可能均衡。
-
-
当Kafka 集群要触发重平衡机制时
-
在重平衡开始之前,Kafka 会暂停所有消费者的拉取操作
-
计算分区分配方案
- 分区分配方案确定之后,Kafka 集群会将分配方案发送给每个消费者,并请求它们重新加入消费者组。
- Kafka 集群会重新分配主题分区给各个消费者。
-
Kafka 会恢复所有消费者的拉取操作
-
6.Kafka 消息的发送过程
-
Main线程创建消费者实例并执行发送逻辑到RecordAccumulator
-
RecordAccumulator起到了消息积累和批量发送的作用
-
sender线程会从RecordAccumulator的待发送队列中取出消息,发送到对应Partition 的 Leader Broker
-
7.ISR
-
在Kafka中,每个主题分区可以有多个副本(replica),ISR是与主副本(Leader Replica)保持同步的副本集合,用于确保数据的可靠性和一致性的。
-
当消息被写入Kafka的分区时,它首先会被写入Leader,然后Leader将消息复制给ISR中的所有副本。只有当ISR中的所有副本都成功地接收到并确认了消息后,主副本才会认为消息已成功提交。
8.kafka的选举过程
-
Partition Leader 选举
-
Kafka 中的每个 Partition 都有一个 Leader,负责处理该 Partition 的读写请求
-
在正常情况下,Leader 和 ISR 集合中的所有副本保持同步,Leader 接收到的消息也会被 ISR 集合中的副本所接收。
-
Leader 选举的过程如下:
-
每个参与选举的副本会尝试向 ZooKeeper 上写入一个临时节点,并将自己的节点序列号写入该节点,节点序列号最小的副本会被选为新的 Leader,并将自己的节点名称写入 ZooKeeper 上的 /broker/.../leader 节点中。
-
-
-
Controller 选举
-
Kafka 集群中只能有一个 Controller 节点,用于管理分区的副本分配、leader 选举等任务。
-
Controller选举的过程如下
-
当一个 Broker 发现 Controller 失效时,ZooKeeper会删除 /controller 节点,它会向 ZooKeeper 写入自己的 ID,并尝试竞选 Controller 的位置。如果他创建临时节点成功,则该 Broker 成为新的 Controller,并将选举结果写入 ZooKeeper 中。
-
为了避免出现多个 Broker 同时竞选 Controller 的情况,Kafka 设计了一种基于 ZooKeeper 的 Master-Slave 机制,其中一个 Broker 成为 Master,其它 Broker 成为 Slave。Master 负责选举 Controller,并将选举结果写入 ZooKeeper 中,而 Slave 则监听 /controller 节点的变化,一旦发现 Master 发生故障,则开始争夺 Master 的位置。
-
-
-
9.高水位与Leader Epoch
-
高水位
-
高水位保证消费的可靠性,标识了一个特定的消息偏移量(offset),即一个分区中偏移量前代表已提交可以消费,所以消费者只能拉取到这个 offset 之前的消息
-
消费者可以通过跟踪高水位来确定自己消费的位置。原理为消费者可以通过记录上一次消费的偏移量,然后将其与分区的高水位进行比较,来确定自己的消费进度
-
-
-
Leader Epoch
- Leader Epoch是一个递增的整数,每次副本切换时都会增加。它用于标识每个Leader副本的任期。
-
用于标识每个Leader副本的任期,每个 Leader 任期都有一个唯一的 Leader Epoch 编号,确保新的 Leader 任期的编号总是比旧的 Leader 大
-
- Leader Epoch是一个递增的整数,每次副本切换时都会增加。它用于标识每个Leader副本的任期。
-
Leader Epoch作用
-
在分区副本切换过程中,新的Leader会检查旧Leader副本的Leader Epoch和高水位。只有当旧Leader副本的Leader Epoch小于等于新Leader副本的Leader Epoch,并且旧Leader副本的高水位小于等于新Leader副本的高水位时,新Leader副本才会接受旧Leader副本的数据,避免新的Leader副本接受旧Leader副本之后的消息(即避免避免数据回滚)
-