Kafka 中的核心概念


文章目录

  • 一、MQ 的作用
  • 二、Kafka 的核心概念
    • 1. Kafka 概述
    • 2. Kafka 中的核心概念
  • 三、zookeeper 在 kafka 中的作用
    • 1. Controller 选举机制
    • 2. Partition Leader 选举机制
    • 3. Partition 故障恢复机制

一、MQ 的作用


MQ(MessageQueue),Message 是跨进程传递的信息,Queue 是 FIFO(先进先出)的数据结构。

所有的 MQ 类型产品都有以下三个主要作用:

  1. 异步:
    提⾼系统的响应速度、吞吐量。
    如:服务器将消息丢给 MQ 后,就可以直接处理后续请求,而不必等待。
  2. 解耦:
    减少服务之间的影响,提⾼系统整体的稳定性以及可扩展性。
    如:服务器间不直接通信,而是通过 MQ,当新增或移除服务器时不会影响到已有服务器。
  3. 削峰:
    应对突发的流量冲击。
    当流量过大时,可以将请求缓存在 MQ 中,以应对流量冲击。

二、Kafka 的核心概念

1. Kafka 概述


Kafka 是 MQ 的一种具体实现,它以 发布-订阅 的模式来传递消息,早期的 Kafka 的使用包括集群都需要搭配 Zookeeper,从 Kafka 4.0 开始,放弃了 Zookeeper,通过自己的 Kraft 组件实现集群管理。

Kafka 是一种可用性优先于数据安全性的 MQ 产品,并且利用了零拷贝和顺序写机制提高性能。所以其特点是:⾼吞吐量、高可用、低延迟,但是会发生也允许发生少量数据的丢失(这并不是设计缺陷,而是默认配置就是倾向于高吞吐量,可以通过更改配置来实现零数据丢失,但是会牺牲性能)。

2. Kafka 中的核心概念


1. Kafka 中的核心概念:

  1. 服务器:安装 Kafka 应用的机器就是服务器。
  2. 客户端:
    • 生产者(Producer):主要用来将消息发送到 Kafka 服务器
    • 消费者(Consumer):主要从 Kafka 服务器中拉取消息。

它们的关系如下:

Kafka 中的核心概念_第1张图片

2. 进一步细分 Kafka 中的核心概念:

  • Broker:一个 Kafka 服务器就是一个 Broker,多个 Broker 可以构成 Kafka 集群,然后会选举出一个 Controller Broker,用来管理整个集群的信息
  • 主题(Topic):生产者发送消息时要指定一个主题,消费者拉取消息时也需要指定一个主题。
  • 分区(Partition):发送到主题中的数据会被分散在各个分区中存储,每个分区可以有多个备份,然后在多个备份中选举出一个 Leader 分区,只有 Leader 分区才能被客户端操作。
  • 消费者组:对于每个消费者,可以为其指定⼀个消费者组。kafka 中的⼀条消息被消费者拉取后,同组内的其他消费者,就不能再次拉取,但其他消费者组中的消费者仍然可以继续拉取这条消息。

进一步细分后关系如下:

Kafka 中的核心概念_第2张图片

图中内容解释:

图中是两个 broker 组成的 kafka 集群,两个 broker 中拥有相同的主题 topic1 和 topic2,每个主题内的消息都分散在两个分区中 partition1 和 partition2。

partition1 和 partition2 又分别被复制一份,所以一个主题下会有四个分区 partition1 Leader、partition1 Follow、partition2 Leader、partition2 Follow,

因为只有 Leader 分区才会响应客户端请求,如果把 partition1 Follow 和 partition2 Follow 放到同一个 Broker 中,会导致该 Broker 闲置,浪费性能,所以为了充分利用机器性能,partition 1 和 partition 2 的 Leader 分区被分开存放到两个 Broker 中。

3. 进一步细分 Kafka 生产者中的核心概念:

  • RecordAccumulator:RecordAccumulator 的内部会保存多个和 Partition 一一对应的 双端队列 DQueue,生产者发送的消息会先缓存到这个 DQueue 中。
  • Sender 线程:Sender 会从 RecordAccumulator 的 DQueue 中拉取待发送的消息,并封装成真正的 请求对象(InflightRequest)后发送,发送后会将 InflightRequest 缓存在 InflightBatch 中,直到 Broker 返回 ACK 后,才将 InflightRquest 从 InflightBatch 中移除。

相对完整一点的 Kafka 各部件关系如下:

Kafka 中的核心概念_第3张图片

三、zookeeper 在 kafka 中的作用


Kafka 采取状态信息和消息分离的设计思想,将各个 Broker 的状态信息保存在 Zookeeper 中,将消息保存在 Broker 本地。

Zookeeper 中保存的状态信息最为主要的有两个:

  • Controller 信息:Kafka 集群时,需要选举出⼀个Broker 担任 Controller ⻆⾊,由 Controller ⻆⾊来管理整个集群中的分区和副本状态。
  • Leader 信息:在同⼀个 Topic 下的多个 Partition 中,需要选举出⼀个 Leader ⻆⾊。由 Leader ⻆⾊的 Partition 来负责与客户端进⾏数据交互。

1. Controller 选举机制


Controller 的选举,使用的是抢占式的方式。当集群中的 Broker 启动时,会尝试在 Zookeeper 中创建一个 /Controller 临时节点,并将自己的 brokerId 写到节点中。创建 /Controller 临时节点成功的那个 Broker 就是 Controller。

其他未成功创建的 Broker 则会监听这个 /Controller 临时节点,一旦 /Controller 临时节点被删除了,则会触发监听器,所有 Broker 会重新抢占 /Controller 临时节点。

选举产⽣的 Controller 节点,就会负责监听 Zookeeper 中的⼀些关键节点:

  • 监听 Zookeeper 中的 /brokers/ids 节点,感知 Broker 增减变化
  • 监听 Zookeeper 中的 /brokers/topics 节点,感知 topic 以及对应的 partition 的增减变化
  • 负责将元数据推送给其他 Broker

2. Partition Leader 选举机制


在 Kafka 中,一个 Topic 的所有消息,会被分开存储到不同的 Partition 中,而每个 Partition 又可以进行复制备份。在 Partition 的众多备份中,需要选举出⼀个Leader Partition,负责对接所有的客户端请求,并将消息优先保存,然后再通知其他 Follower Partition 来同步消息。

Partition Leader 的选举机制⾮常简单⾼效。在选举 Leader Partition 时,会按照 ISR(每个分区存活的副本集合) 中的排名顺序,靠前的优先选举。当选举完成后,Zookeeper 中的信息也会被及时更新,这样选举结果,就可以在所有 Broker 中达成共识。

3. Partition 故障恢复机制


想明白 Partition 故障恢复前,需要先明白两个概念:

  • LEO(Log End Offset):最新 offset。Leader 每收到一条消息,Leader 分区保存的 offset 就会加 1,Follow 每同步一条消息,该 Follow 副本的 offset 也会加 1。
  • HW:所有副本中最小的 offset。每次 Follow 和 Leader 同步时,都会将副本自己保存的 offset 上传给 Leader,然后 Leader 从所有副本的 Offset 中选择 一个最小的作为 HW,然后同步给所有 Follow 让其保存。HW 是一个分界线,HW 之前的消息,代表所有副本都已经同步过,是安全的消息。HW 之后的消息,代表有些副本还没有同步过,是不安全的。

有了上面的基础,就很好理解故障恢复机制。

第一种情况, Follow 节点发生了故障,这个时候其实对整个集群没有什么影响,无非就是少了一个备份,会将其踢出 ISR。 当 Follow 节点恢复时,并不会直接加入到 ISR 中,而是将高于自己本地保存的 HW 的信息全部删除,然后以本地保存的 HW 为起点对 Leader 发起同步,等到该 Follow 的 LEO >= 最新的 HW 后,才会重新加入 ISR。

第二种情况,Leader 节点发生了故障,Leader 节点会被踢出 ISR,然后从 ISR 中重新选举新的 Leader。当新的 Leader 确定后,所有 Follow 节点会将 HW 之后的消息全部删除,然后从 新 Leader 中同步。当 旧的 Leader 恢复后,将作为 Follow 节点进行数据恢复。

在 Leader 节点发生故障的这种场景下,当 HW 过小时,新 Leader 选举成功后,很有可能发生数据丢失,这是 Kafka 允许的,因为 Kafka 默认的理念就是可用性大于数据安全性。

你可能感兴趣的:(#,Kafka,kafka)