Kafka 元数据管理

KIP-500

在 Kafka2.8 之前,Kafka 一直使用 Zookeeper1来存储和管理 Partition3和 Broker4的元数据。以及选举一个 Broker 作为 Kafka 控制器

Kafka 与 Zookeeper5

Kafka 移除 Zookeeper1的动机

  1. 提高元数据管理的鲁棒性和可扩展性
  2. 支持更多分区
  3. 减少部署和配置难度

架构

image

当前,一个 Kafka 集群包含多个 broker 节点和一个外部的 ZooKeeper 仲裁节点。我们在这个图中描绘了 4 个 broker 节点和 3 个 ZooKeeper 节点,这是一个小型集群的典型规模。Kafka 控制器(用橙色表示)在选举后从 ZooKeeper 仲裁节点加载其状态。控制器向其他 broker 节点推送更新,例如 LeaderAndIsr 和 UpdateMetadata 消息。

请注意,这个图有些误导。除了控制器,其他 broker 也会与 ZooKeeper 通信。因此,实际上应该从每个 broker 到 ZK 画线。然而,画这么多线会使图表难以阅读。另一个问题是,这个图省略了外部命令行工具和实用程序可以在没有控制器参与的情况下修改 ZooKeeper 中的状态。 如前所述,这些问题使得很难确定控制器内存中的状态是否真正反映了 ZooKeeper 中的持久状态。

在提出的架构中,三个控制器节点替代了三个 ZooKeeper 节点。控制器节点和 broker 节点在不同的 JVM 中运行。控制器节点为元数据分区选举出一个单一的领导者,显示为橙色。与控制器向 broker 推送更新不同,broker 从该领导者拉取元数据更新。这就是为什么箭头指向控制器而不是指向外的原因。

请注意,虽然控制器进程在逻辑上与 broker 进程是分开的,但它们不必在物理上分开。在某些情况下,将部分或全部控制器进程部署在与 broker 进程相同的节点上是有意义的。这类似于在较小集群中,ZooKeeper 进程可能与 Kafka brokers 部署在同一节点上的方式。与往常一样,所有部署选项都是可能的,包括在同一 JVM 中运行。

控制器的法定人数(Quorum)

控制器节点构成了一个 Raft 算法2的仲裁集群,负责管理元数据日志。该日志包含关于集群元数据每次更改的信息。当前存储在 ZooKeeper 中的所有内容,例如主题、分区、ISR、配置等,都将存储在这个日志中。

使用 Raft 算法2,控制器节点将在内部选举出一个领导者,而不依赖任何外部系统元数据日志的领导者称为活动控制器(active controller)。 活动控制器处理来自 Broker4 的所有 RPC 请求。活动控制器的从节点会复制写入活动控制器的数据,并在活动控制器发生故障时充当热备份。由于所有控制器都会跟踪最新状态,控制器的故障切换将不需要漫长的重新加载时间,因为我们不需要将所有状态转移到新控制器。

与 Zookeeper1 类似,Raft 要求大多数节点必须运行才能继续运行。因此,一个三节点的控制器集群可以承受一次故障。五节点的控制器集群可以承受两次故障,以此类推。 控制器会定期将元数据的快照写入磁盘。虽然在概念上这与压缩类似,但代码路径会有所不同,因为我们可以直接从内存中读取状态,而不是重新从磁盘读取日志。

broker 元数据管理

与控制器向其他 broker 推送更新不同,这些 broker 将通过新的 MetadataFetch API 从活动控制器获取更新。模式由 controller push 变为了 brokers pull

MetadataFetch 类似于 fetch 请求。与 fetch 请求一样,broker 将跟踪它最后获取的更新的偏移量,仅请求活动控制器的更新。 broker 会将获取的元数据持久化到磁盘,这将允许 broker 快速启动,即使存在成千上万甚至数百万个分区。

大多数情况下,broker 只需获取增量更新,而不需要获取完整状态。然而如果 broker 落后于活动控制器太多,或者 broker 根本没有缓存的元数据,控制器将发送完整的元数据快照,而不是一系列增量更新。

broker 会定期向活动控制器请求元数据更新。这个请求将同时充当心跳,向控制器表明 broker 仍然存活。

image

broker 状态机

在 2.8 版本之前 broker 在启动后会立即向 ZooKeeper 注册。这个注册完成了两个目的

  1. 让 broker 知道自己是否被选为控制器
  2. 让其他节点知道如何联系它。

之后则是 broker 将向控制器集群注册

image

Offline

当 broker 进程处于离线状态时,它要么完全未运行,要么正在执行启动所需的单节点任务,例如初始化 JVM 或执行日志恢复。

Fenced

当 broker 处于隔离状态时,它不会响应来自客户端的 RPC 请求。在启动并尝试获取最新元数据时,broker 将处于隔离状态。如果无法联系活动控制器,它将重新进入隔离状态。 隔离的 broker 应在发送给客户端的元数据中省略。

Online

当 broker 在线时,它准备好响应来自客户端的请求。

Stopping

当 broker 收到 SIGINT 信号时,它会进入停止状态。这表明系统管理员希望关闭 broker。在停止过程中,broker 仍然在运行,但我们正在尝试将分区领导者迁移到其他 broker。最终,活动控制器将通过在 MetadataFetchResponse 中返回特殊结果代码,要求 broker 最终进入离线状态。或者,如果无法在预定时间内迁移领导者,broker 将关闭。


  1. Zookeeper

    Zookeeper 是一个高性能、高可靠的分布式协调系统,是 Google Chubby 的一个开源实现。Zookeeper 能够为分布式应用提供一致性服务,提供的功能包括:配置维护、域名服务、分布式同步、组服务等。

    Zookeeper 使用 Zab 协议传递 leader 的状态改变,保证 leader 与 follower 的一致性。Zab 全称 Zookeeper Atomic Broadcast protocol,是 Paxos 算法[^2] 的经典实现。

    Zookeeper 应用非常广泛,应用场景主要包括

    *     **数据发布订阅(配置中心)**
    
    • **命名服务(保存全局唯一 ID)**
      
    • **分布式协调服务(Watcher、异步通知)**
      
    • **心跳检测(临时节点)**
      
    • **任务进度上报(临时节点)**
      
    • **Master 选举(临时节点、Watcher)**
      
    • **分布式锁(临时节点、Watcher)**
      

    前面介绍说 Zookeeper 是一个高性能、高可靠的系统,之所以是高性能主要因为 Zookeeper 保存在内存中,此外 Zookeeper 通常是集群模式,不存在单点故障即保证了其可靠性。

  2. Raft 算法

    Raft 算法

  3. Partition

    Parition 是物理上的概念,每个 Topic 包含一个或多个 Partition。这些 Partition 可能分布在不同的 Broker 上。

  4. Broker

    Kafka Broker 是 Kafka 集群中的一台服务器,负责管理消息的存储和处理。一个 Kafka 集群可以包含多个 Broker,这些 Broker 共同工作以确保高可用性和数据持久性。

    主要功能

    *     消息接收:Broker 接收来自生产者(Producer[^18])发送的消息,并将其存储在主题(Topic)中。
    
    • 消息存储:kafka 消息接收和存储流程[^19]
      
    • 消息转发:Broker 根据消费者的请求,将存储的消息转发给相应的消费者。
      
    • 副本管理:Kafka 通过复制机制来确保数据的高可用性。每个Partition[^16]可以有多个副本(Replicas),分布在不同的 Broker 上。
      

    负载均衡与扩展

    *     负载均衡:通过将Topic[^24]划分为多个分区,并将这些分区分布到不同的 Broker 上可以实现负载均衡。
    
    • 水平扩展:可以通过增加新的 Broker 来扩展 Kafka 集群,以处理更多的消息流和存储需求。
      

    消息的生命周期

    kafka 消息接收和存储流程[^19]

    配置和管理

    *     Kafka 提供了一系列配置选项,用于控制 Broker 的行为,如:
    
      *     `num.partitions`:主题的默认分区数。
    
    • `log.retention.hours`:控制消息在 Broker 中的保留时间。
      
    • `replication.factor`:设置每个分区的副本数量。
      
  5. Kafka 与 Zookeeper

    Zookeeper1在 Kafka 架构中扮演着重要角色。Kafka 使用 Zookeeper 进行元数据管理,保存 broker 注册的信息,包括 Topic、Partition 信息等,选举 Partition Leader,低版本 Kafka Consumer 的 offset 信息也保存在 Zookeeper 中。

    集群成员注册

    每个加入 Kafka 集群的 broker 会在 ZooKeeper 上注册一个临时的 znode。

    控制器选举

    当 broker 启动时,它尝试通过在 ZooKeeper 上创建临时的 /controller znode 来担任“控制器”角色。如果该 znode 已存在,则指示当前的控制器是哪个 broker。

    Topic 配置

    所有 topic 配置属性,例如分区数量和副本的当前 broker 分配,都会存储在 ZooKeeper 中。

    访问控制列表 (ACLs)

    当客户端连接到集群时,可以根据内置授权者在 ZooKeeper 中存储的 ACL 进行身份验证和授权,以读取或写入多个主题。

    配额

    broker 可以通过内置的配额提供者在 ZooKeeper 中存储的配额来限制客户端使用的资源,包括网络带宽和 CPU 利用率。

  • Kafka

    Kafka 是一种高吞吐量的分布式发布订阅消息系统,它可以处理消费者规模的网站中的所有动作流数据。 这种动作(网页浏览,搜索和其他用户的行动)是现代系统中许多功能的基础。 这些数据通常是由于吞吐量的要求而通过处理日志和日志聚合来解决。

    36 引用 • 35 回帖 • 2 关注
  • 算法
    428 引用 • 254 回帖 • 24 关注
  • 分布式
    80 引用 • 149 回帖 • 4 关注

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...