Kafka 基础知识

Kafka 是一个分布式流式处理平台。

流平台具有三个关键功能:

  1. 消息队列:发布和订阅消息流,这个功能类似于消息队列,这也是 Kafka 也被归类为消息队列的原因。
  2. 容错的持久方式存储记录消息流: Kafka 会把消息持久化到磁盘,有效避免了消息丢失的风险·。
  3. 流式处理平台: 在消息发布的时候进行处理,Kafka 提供了一个完整的流式处理类库。

Kafka 主要有两大应用场景:

  1. 消息队列 :建立实时流数据管道,以可靠地在系统或应用程序之间获取数据。
  2. 数据处理: 构建实时的流数据处理程序来转换或处理数据流。

关于 Kafka 几个非常重要的概念:

  1. Kafka 将记录流(流数据)存储在 topic 中。
  2. 每个记录由一个键、一个值、一个时间戳组成。

Kafka 组件

在深入了解 Kafka 之前,您必须了解主要术语,例如主题、代理、生产者和消费者。下图说明了主要术语,表格详细描述了图表组件。

基本面

在上图中,一个主题配置为三个分区。分区 1 有两个偏移因子 0 和 1。分区 2 有四个偏移因子 0、1、2 和 3。分区 3 有一个偏移因子 0。副本的 id 与托管它的服务器的 id 相同。

假设主题的复制因子设置为 3,那么 Kafka 将为每个分区创建 3 个相同的副本,并将它们放置在集群中,以供所有操作使用。为了平衡集群中的负载,每个代理都会存储一个或多个分区。多个生产者和消费者可以同时发布和检索消息。

序号组件描述
1主题属于特定类别的消息流称为主题。数据存储在主题中。主题被分成多个分区。对于每个主题,Kafka 至少保留一个分区。每个分区都包含按不可变顺序排列的消息。分区实现为一组大小相同的段文件。
2分区主题可能有许多分区,因此它可以处理任意数量的数据。
3分区偏移每个分区消息都有一个唯一的序列 ID,称为偏移量。
4分区副本副本只不过是分区的备份。副本永远不会读取或写入数据。它们用于防止数据丢失。
5代理代理是负责维护已发布数据的简单系统。每个代理可能对每个主题有零个或多个分区。假设,如果一个主题中有 N 个分区,并且有 N 个代理,则每个代理将有一个分区。假设一个主题中有 N 个分区,且有超过 N 个代理(n + m),则第一个 N 代理将有一个分区,而下一个 M 代理将没有针对该特定主题的任何分区。假设一个主题中有 N 个分区,而 Broker 数量少于 N 个(n - m),则每个 Broker 之间将共享一个或多个分区。由于 Broker 之间的负载分配不均,因此不建议采用此方案。
6Kafka 集群拥有多个 代理 的 Kafka 称为 Kafka 集群。Kafka 集群可以在不停机的情况下进行扩展。这些集群用于管理消息数据的持久性和复制。
7生产者生产者是向一个或多个 Kafka 主题发布消息的人。生产者将数据发送到 Kafka 代理。每次生产者向代理发布消息时,代理都会将消息附加到最后一个段文件。实际上,该消息将附加到分区。生产者还可以将消息发送到他们选择的分区。
8消费者消费者从代理读取数据。消费者订阅一个或多个主题,并通过从代理提取数据来使用已发布的消息。
9领导者Leader是负责给定分区的所有读写的节点。每个分区都有一台服务器充当 Leader。
10追随者遵循领导者指令的节点称为追随者。如果领导者失败,追随者之一将自动成为新的领导者。追随者充当普通消费者,提取消息并更新自己的数据存储。

一个 Kafka 集群有多个 Broker,一个 Broker 可以有多个 Topic,一个 Topic 可以有多个 Partition,一个 Partition 可以有多个副本,并且同一 Topic 下的 Partition 可以分布在不同的 Broker 上,这也就表明一个 Topic 可以横跨多个 Broker 。

Partition 中的多个副本之间会有一个叫做 leader 的家伙,其他副本称为 follower。我们发送的消息会被发送到 leader 副本,然后 follower 副本才能从 leader 副本中拉取消息进行同步。

生产者和消费者只与 leader 副本交互。你可以理解为其他副本只是 leader 副本的拷贝,它们的存在只是为了保证消息存储的安全性。当 leader 副本发生故障时会从 follower 中选举出一个 leader,但是 follower 中如果有和 leader 同步程度达不到要求的参加不了 leader 的竞选。

Kafka 的多分区(Partition)以及多副本(Replica)机制有什么好处呢?

  1. Kafka 通过给特定 Topic 指定多个 Partition, 而各个 Partition 可以分布在不同的 Broker 上, 这样便能提供比较好的并发能力(负载均衡)。
  2. Partition 可以指定对应的 Replica 数, 这也极大地提高了消息存储的安全性, 提高了容灾能力,不过也相应的增加了所需要的存储空间。

Kafka 架构

集群架构

序号组件描述
1代理Kafka 集群通常由多个代理组成,以保持负载平衡。Kafka 代理是无状态的,因此它们使用 ZooKeeper 来维护其集群状态。一个 Kafka 代理实例每秒可以处理数十万次读写,每个代理可以处理 TB 级消息而不会影响性能。Kafka 代理领导者选举可以通过 ZooKeeper 完成。
2ZooKeeperZooKeeper 用于管理和协调 Kafka 代理。ZooKeeper 服务主要用于通知生产者和消费者有关 Kafka 系统中任何新代理的存在或 Kafka 系统中代理的故障。根据 Zookeeper 收到的有关代理存在或故障的通知,生产者和消费者做出决定并开始与其他代理协调他们的任务。
3生产者生产者将数据推送到代理。当新代理启动时,所有生产者都会搜索它并自动向该新代理发送消息。Kafka 生产者不会等待代理的确认,而是以代理可以处理的速度发送消息。
4消费者由于 Kafka 代理是无状态的,这意味着消费者必须使用分区偏移量来维护已消费的消息数量。如果消费者确认了特定的消息偏移量,则意味着消费者已经消费了所有先前的消息。消费者向代理发出异步拉取请求,以便准备好可供消费的字节缓冲区。消费者只需提供偏移量值即可倒回或跳转到分区中的任何点。消费者偏移量值由 ZooKeeper 通知。

Kafka 消息模型

早期的消息模型有两种:队列模型、发布-订阅模型。

使用队列(Queue)作为消息通信载体,满足生产者与消费者模式,一条消息只能被一个消费者使用,未被消费的消息在队列中保留直到被消费或超时。

列模型存在的问题:假如我们存在这样一种情况:我们需要将生产者产生的消息分发给多个消费者,并且每个消费者都能接收到完成的消息内容。这种情况,队列模型就不好解决了。

发布-订阅模型主要是为了解决队列模型存在的问题。

发布订阅模型(Pub-Sub) 使用主题(Topic) 作为消息通信载体,类似于广播模式;发布者发布一条消息,该消息通过主题传递给所有的订阅者,在一条消息广播之后才订阅的用户则是收不到该条消息的

在发布 - 订阅模型中,如果只有一个订阅者,那它和队列模型就基本是一样的了。所以说,发布 - 订阅模型在功能层面上是可以兼容队列模型的。

Kafka 采用的就是发布 - 订阅模型。

RocketMQ 的消息模型和 Kafka 基本是完全一样的。唯一的区别是 Kafka 中没有队列这个概念,与之对应的是 Partition(分区)。

Zookeeper 作用

这部分内容参考和借鉴了这篇文章:https://www.jianshu.com/p/a036405f989c 。

ZooKeeper 主要为 Kafka 提供元数据的管理的功能:

  1. Broker 注册 :在 Zookeeper 上会有一个专门用来进行 Broker 服务器列表记录的节点。每个 Broker 在启动时,都会到 Zookeeper 上进行注册,即到/brokers/ids 下创建属于自己的节点。每个 Broker 就会将自己的 IP 地址和端口等信息记录到该节点中去
  2. Topic 注册 : 在 Kafka 中,同一个Topic 的消息会被分成多个分区并将其分布在多个 Broker 上,这些分区信息及与 Broker 的对应关系也都是由 Zookeeper 在维护。比如我创建了一个名字为 my-topic 的主题并且它有两个分区,对应到 zookeeper 中会创建这些文件夹:/brokers/topics/my-topic/Partitions/0/brokers/topics/my-topic/Partitions/1
  3. 负载均衡 :上面也说过了 Kafka 通过给特定 Topic 指定多个 Partition, 而各个 Partition 可以分布在不同的 Broker 上, 这样便能提供比较好的并发能力。 对于同一个 Topic 的不同 Partition,Kafka 会尽力将这些 Partition 分布到不同的 Broker 服务器上。当生产者产生消息后也会尽量投递到不同 Broker 的 Partition 里面。当 Consumer 消费的时候,Zookeeper 可以根据当前的 Partition 数量以及 Consumer 数量来实现动态负载均衡。
Share this post:

Related content