基础名词
- Broker:Kafka 集群中的一台服务器,负责存储和转发消息。一个集群可以有多个 Broker
- Topic:Kafka 中的消息主题,类似于消息队列的名称。一个 Topic 可以有多个分区
- Partition:Topic 的分区,每个 Topic 可以有多个分区。每个分区是一个有序的消息队列
- Producer:生产者,负责向 Kafka 发送消息
- Consumer:消费者,负责从 Kafka 中消费消息
- Consumer Group:消费者组,多个消费者可以组成一个消费者组,共同消费一个 Topic 的消息
- 每个消费者组可以有多个消费者
- 每个分区只能被一个消费者组中的一个消费者消费
- 多个消费者组可以同时消费同一个 Topic 的消息
- 多个消费者组可以同时消费同一个 partition 的消息
- Offset:消息在分区中的位置
- 每个消息都有一个唯一的 Offset,表示它在分区中的位置
- Offset 是一个递增的数字,从 0 开始
- 以消费者组为单位,每个消费者组都有自己的 Offset
- Controller: Kafka 集群中的一个 Broker
- 负责管理集群中的所有 Broker 和 Topic
- 负责分区的 Leader 选举和副本的同步
为什么快
- 顺序写入的方式,减少了随机写入的性能损耗
- 零拷贝,直接在磁盘和网络之间传输数据,减少了内存的拷贝
- 分区并行处理,多个分区可以同时被多个消费者消费,提高了吞吐量
- 批量处理,将多个消息合并成一个批量进行处理,减少了网络传输的开销
- 对消息进行压缩,减少了网络传输的开销
如何保证消息顺序
- 分区:Kafka 将消息分为多个分区,每个分区内的消息是有序的
- 分区键:在发送消息时,可以指定一个分区键,Kafka 会根据分区键将消息发送到对应的分区
- 无法保证全局顺序:Kafka 只能保证同一分区内的消息是有序的,无法保证全局顺序
选举
Controller 的选举
选举过程
- Controller 的选举是通过 ZooKeeper 来完成的
- 所有 Broker 启动时都会尝试在 ZooKeeper 中创建一个临时节点,只有一个 Broker 能够成功创建这个节点,这个 Broker 就成为 Controller
- 如果 Controller 挂掉,ZooKeeper 会删除这个节点,其他 Broker 会重新尝试创建节点,第一个成功创建的 Broker 就成为新的 Controller
- 2.8 版本之后,Kafka 引入了 Raft 协议来替代 ZooKeeper 进行 Controller 的选举
分区 Leader 的选举
名词解释
- Replica:副本,Kafka 中的每个 Partition 都有一个或多个副本,用于保证数据的可靠性
- Leader:主副本,负责处理读写请求。生产者和消费者都通过 Leader 来读写数据
- Follower:从副本,负责复制 Leader 的数据。不处理读写请求
- ISR:In-Sync Replica,表示当前与 Leader 同步的副本列表
选举过程
- 优先从 ISR 列表中选择第一个活跃的副本作为 Leader
- 如果 ISR 列表为空,则根据配置选择以下不同策略:
- 等待 ISR 列表有可用副本
- 允许选择非 ISR 列表中的副本作为 Leader
副本同步机制
名词解释
- LEO:Log End Offset,表示当前副本的最新消息的 Offset
- HW:High Watermark,ISR 列表中所有副本中 LEO 最小的值,表示消费者可以消费的最新消息的 Offset
ISR 维护
- 进入 ISR 的条件
- 副本首次创建时会进入 ISR
- 副本同步进度追上 Leader 时会进入 ISR
- 离开 ISR 的条件
- 副本与 Leader 断开连接
- 副本的同步落后太多(延迟超过配置的时间)
同步机制
- 生产者发送消息给 Leader
- Leader 写入消息,并更新自己的 LEO
- Follower 从 Leader 拉取消息,并更新自己的 LEO
- Leader 会跟踪所有 Follower 的 LEO
- Leader 取所有 ISR 副本中 LEO 最小的值作为 HW
- HW 会随着 LEO 的更新而更新
- 消费者只能消费 HW 之前的消息
以上机制确保了消息的可靠性和一致性
- 数据可靠性:数据只有在所有 ISR 副本都同步完成后才会被消费者消费
- 数据一致性:所有消费者看到的消息都是一致的,保证了消息的顺序性
- 可用性:如果 Leader 挂掉,Kafka 会自动选择新的 Leader,保证了系统的高可用性