在 RHEL 上使用 AMQ Streams

Red Hat AMQ Streams 2.5

在 Red Hat Enterprise Linux 中配置和管理 AMQ Streams 2.5 部署

摘要

配置使用 AMQ Streams 部署的 operator 和 Kafka 组件,以构建大规模消息传递网络。

使开源包含更多

红帽致力于替换我们的代码、文档和 Web 属性中存在问题的语言。我们从这四个术语开始:master、slave、黑名单和白名单。由于此项工作十分艰巨,这些更改将在即将推出的几个发行版本中逐步实施。有关更多详情,请参阅我们的首席技术官 Chris Wright 提供的消息

第 1 章 AMQ Streams 概述

Red Hat AMQ Streams 是一个可大规模扩展的、分布式和高性能数据流平台,它基于 Apache ZooKeeper 和 Apache Kafka 项目。

主要组件组成:

Kafka Broker

负责从生成客户端发送到消耗客户端的记录的消息代理。

Apache ZooKeeper 是 Kafka 的一个核心依赖项,为高可靠的分布式协调服务提供集群协调服务。

Kafka Streams API
用于编写 流处理器 应用的 API。
Producer 和 Consumer APIs
基于 Java 的 API,用于向 Kafka 代理生成和使用信息。
Kafka Bridge
AMQ Streams Kafka Bridge 提供了一个 RESTful 接口,它允许基于 HTTP 的客户端与 Kafka 集群交互。
Kafka Connect
使用 Connector 插件在 Kafka 代理和其他系统间流传输数据的工具包。
Kafka MirrorMaker
在两个 Kafka 集群间复制数据,在数据中心内部或跨数据中心复制数据。
Kafka Exporter
用于监控的 Kafka 指标数据中提取中使用的导出器。

Kafka 代理集群是连接所有这些组件的 hub。代理使用 Apache ZooKeeper 来存储配置数据和集群协调。在运行 Apache Kafka 之前,Apache ZooKeeper 集群必须就绪。

图 1.1. AMQ Streams 架构

AMQ Streams 架构

1.1. 使用 Kafka Bridge 与 Kafka 集群连接

您可以使用 AMQ Streams Kafka Bridge API 创建和管理消费者,并通过 HTTP 发送和接收记录,而不是原生 Kafka 协议。

设置 Kafka Bridge 时,您可以配置对 Kafka 集群的 HTTP 访问。然后,您可以使用 Kafka Bridge 来生成和消费来自集群的消息,以及通过其 REST 接口执行其他操作。

其他资源

1.2. 文档惯例

用户替换的值

用户替换的值(也称为 可替换值)显示为包括在尖括号 (< >) 中的斜体字符。下划线(_)用于多词值。如果该值引用代码或命令,也会使用 monospace

例如,在以下代码中,您要将 <bootstrap_address><topic_name> 替换为您自己的地址和主题名称:

bin/kafka-console-consumer.sh --bootstrap-server <bootstrap_address> --topic <topic_name> --from-beginning

第 2 章 FIPS 支持

联邦信息处理标准(FIPS)是计算机安全和互操作性的标准。要将 FIPS 与 AMQ Streams 搭配使用,您必须在您的系统上安装了 FIPS 兼容 OpenJDK (Open Java Development Kit)。如果您的 RHEL 系统是启用了 FIPS 的,OpenJDK 会在运行 AMQ Streams 时自动切换到 FIPS 模式。这样可确保 AMQ Streams 使用 OpenJDK 提供的 FIPS 兼容安全库。

最小密码长度

在 FIPS 模式下运行时,SCRAM-SHA-512 密码至少需要 32 个字符。如果您的 Kafka 集群带有使用小于 32 个字符的密码长度的自定义配置,则需要更新您的配置。如果您有少于 32 个字符的密码,则需要重新生成具有所需长度的密码。

2.1. 安装启用了 FIPS 模式的 AMQ Streams

在 RHEL 上安装 AMQ Streams 前启用 FIPS 模式。红帽建议安装启用了 FIPS 模式的 RHEL,而不是在以后启用 FIPS 模式。在安装过程中启用 FIPS 模式可确保系统使用 FIPS 批准的算法生成所有的密钥,并持续监控测试。

在以 FIPS 模式运行的 RHEL 时,您必须确保 AMQ Streams 配置兼容 FIPS。另外,您的 Java 实现还必须符合 FIPS。

注意

以 FIPS 模式在 RHEL 上运行 AMQ Streams 需要 FIPS 兼容 JDK。我们建议使用 OpenJDK 17.0.6 或更新版本。

流程

  1. 在 FIPS 模式中安装 RHEL。

    如需更多信息,请参阅 RHEL 文档中的 安全强化信息。

  2. 继续安装 AMQ Streams。
  3. 配置 AMQ Streams 以使用 FIPS 兼容算法和协议。

    如果使用,请确保以下配置兼容:

    • JDK 框架必须支持 SSL 密码套件和 TLS 版本。
    • SCRAM-SHA-512 密码长度必须至少为 32 个字符。
重要

确保您的安装环境和 AMQ Streams 配置与 FIPS 要求更改保持合规。

第 3 章 开始使用

AMQ Streams 在 ZIP 文件中分发。ZIP 文件包含以下组件的安装工件:

  • Apache Kafka
  • Apache ZooKeeper
  • Apache Kafka Connect
  • Apache Kafka MirrorMaker
注意

Kafka Bridge 有单独的安装文件。有关安装和使用 Kafka Bridge 的详情,请参考使用 AMQ Streams Kafka Bridge

3.1. 安装环境

AMQ Streams 在 Red Hat Enterprise Linux 中运行。主机(节点)可以是物理或虚拟机(VM)。使用 AMQ Streams 提供的安装文件来安装 Kafka 组件。您可以在单节点或多节点环境中安装 Kafka。

单节点环境
单节点 Kafka 集群在单个主机上运行一个或多个 Kafka 代理和 ZooKeeper 实例。此配置不适用于生产环境。
多节点环境
多节点 Kafka 集群在多个主机上运行一个或多个 Kafka 代理和 ZooKeeper 实例。

建议您在单独的主机上运行 Kafka 和其他 Kafka 组件,如 Kafka Connect。通过以这种方式运行组件,可以更轻松地维护和升级每个组件。

Kafka 客户端使用 bootstrap.servers 配置属性与 Kafka 集群建立连接。如果使用 Kafka Connect,例如,Kafka Connect 配置属性必须包含 bootstrap.servers 值,用于指定运行 Kafka 代理的主机的主机名和端口。如果 Kafka 集群在多个带有多个 Kafka 代理的主机上运行,您可以为每个代理指定一个主机名和端口。每个 Kafka 代理都由 broker.id 标识。

3.1.1. 支持的环境版本

AMQ Streams 必须在受支持的 Red Hat Enterprise Linux 版本中运行。环境还必须使用受支持的 JVM 版本。如需更多信息,请参阅 支持的配置

3.1.2. 数据存储注意事项

高效的数据存储基础架构对于 AMQ Streams 的性能至关重要。

需要块存储。文件存储(如 NFS)无法用于 Kafka。

从以下选项之一中选择块存储:

  • 基于云的块存储解决方案,如 Amazon Elastic Block Store (EBS)
  • 本地存储
  • 通过协议(如 光纤通道或 iSCSI)访问的存储区域网络(SAN)卷

3.1.3. 文件系统

Kafka 使用文件系统来存储信息。AMQ Streams 与 XFS 和 ext4 文件系统兼容,它们通常与 Kafka 一起使用。选择和设置文件系统时,请考虑部署的底层架构和要求。

如需更多信息,请参阅 Kafka 文档中的 文件系统选择

3.1.4. Apache Kafka 和 ZooKeeper 存储

对 Apache Kafka 和 ZooKeeper 使用单独的磁盘。

Kafka 支持 JBOD (Just a Bunch Disks)存储,这是多个磁盘或卷的数据存储配置。JBOD 为 Kafka 代理提供增加的数据存储。它还可提高性能。

虽然使用固态驱动器 (SSD) 并不是必须的,但它可以在大型集群中提高 Kafka 的性能,其中数据会异步发送到多个主题,并从多个主题接收。SSD 在 ZooKeeper 中特别有用,它需要快速、低延迟数据访问。

注意

您不需要置备复制存储,因为 Kafka 和 ZooKeeper 都有内置数据复制。

其他资源

3.2. 下载 AMQ Streams

AMQ Streams 的 ZIP 文件发布可从红帽网站下载。您可以从 AMQ Streams 软件下载页面下载 Red Hat AMQ Streams 的最新版本。

  • 对于 Kafka 和其他 Kafka 组件,请下载 amq-streams-<version>-bin.zip 文件
  • 对于 Kafka Bridge,下载 amq-streams-<version>-bridge-bin.zip 文件。

    有关安装说明,请参阅使用 AMQ Streams Kafka Bridge

3.3. 安装 Kafka

使用 AMQ Streams ZIP 文件在 Red Hat Enterprise Linux 上安装 Kafka。您可以在单节点或多节点环境中安装 Kafka。在此过程中,单个 Kafka 代理和 ZooKeeper 实例安装在一个主机(节点)上。

AMQ Streams 安装文件包括用于运行其他 Kafka 组件的二进制文件,如 Kafka Connect、Kafka MirrorMaker 2 和 Kafka Bridge。在单节点环境中,您可以从安装 Kafka 的同一主机运行这些组件。但是,我们建议您添加安装文件并在单独的主机上运行其他 Kafka 组件。

注意

如果使用多节点环境,您可以在多个主机上安装 Kafka 代理和 ZooKeeper 实例。为每个主机重复安装步骤。要识别每个 ZooKeeper 实例和代理,您可以在配置中添加唯一的 ID。更多信息请参阅 第 4 章 运行多节点环境

先决条件

流程

在主机上安装带有 ZooKeeper 的 Kafka。

  1. 添加新的 kafka 用户和组:

    groupadd kafka
    useradd -g kafka kafka
    passwd kafka
  2. 提取并将 amq-streams-<version>-bin.zip 文件的内容提取到 /opt/kafka 目录中:

    unzip amq-streams-<version>-bin.zip -d /opt
    mv /opt/kafka*redhat* /opt/kafka

    此步骤需要管理员特权。

  3. /opt/kafka 目录的所有权改为 kafka 用户:

    chown -R kafka:kafka /opt/kafka
  4. 创建目录 /var/lib/zookeeper 以存储 ZooKeeper 数据并将其所有权设置为 kafka 用户:

    mkdir /var/lib/zookeeper
    chown -R kafka:kafka /var/lib/zookeeper
  5. 创建用于存储 Kafka 数据的目录 /var/lib/kafka,并将其所有权设置为 kafka 用户:

    mkdir /var/lib/kafka
    chown -R kafka:kafka /var/lib/kafka

    现在,您可以将 Kafka 的默认配置作为单节点集群运行

    您还可以使用安装在同一主机上运行其他 Kafka 组件,如 Kafka Connect。

    要运行其他组件,请使用组件配置中的 bootstrap.servers 属性指定要连接到 Kafka 代理的主机名和端口。

    指向同一主机上单个 Kafka 代理的 bootstrap 服务器配置示例

    bootstrap.servers=localhost:9092

    但是,我们建议在单独的主机上安装并运行 Kafka 组件。

  6. (可选)在不同的主机上安装 Kafka 组件。

    1. 将安装文件提取到每个主机上的 /opt/kafka 目录中。
    2. /opt/kafka 目录的所有权更改为 kafka 用户。
    3. 添加 bootstrap.servers 配置,将组件连接到运行 Kafka 代理的主机(或多节点环境中的主机)。

      指向不同主机上的 Kafka 代理的 bootstrap 服务器配置示例

      bootstrap.servers=kafka0.<host_ip_address>:9092,kafka1.<host_ip_address>:9092,kafka2.<host_ip_address>:9092

      您可以将此配置用于 Kafka ConnectMirrorMaker 2Kafka Bridge

3.4. 运行单节点 Kafka 集群

此流程演示了如何运行由单个 Apache ZooKeeper 节点和一个 Apache Kafka 节点组成的基本 AMQ Streams 集群,它们在同一主机上运行。默认配置文件用于 ZooKeeper 和 Kafka。

警告

单一节点 AMQ Streams 集群不提供可靠性和高可用性,仅适用于开发目的。

先决条件

  • AMQ Streams 已安装在主机上

运行集群

  1. 编辑 ZooKeeper 配置文件 /opt/kafka/config/zookeeper.properties。将 dataDir 选项设置为 /var/lib/zookeeper/:

    dataDir=/var/lib/zookeeper/
  2. 编辑 Kafka 配置文件 /opt/kafka/config/server.properties。将 log.dirs 选项设置为 /var/lib/kafka/

    log.dirs=/var/lib/kafka/
  3. 切换到 kafka 用户:

    su - kafka
  4. 启动 ZooKeeper:

    /opt/kafka/bin/zookeeper-server-start.sh -daemon /opt/kafka/config/zookeeper.properties
  5. 检查 ZooKeeper 是否正在运行:

    jcmd | grep zookeeper

    返回:

    number org.apache.zookeeper.server.quorum.QuorumPeerMain /opt/kafka/config/zookeeper.properties
  6. 启动 Kafka:

    /opt/kafka/bin/kafka-server-start.sh -daemon /opt/kafka/config/server.properties
  7. 检查 Kafka 是否正在运行:

    jcmd | grep kafka

    返回:

    number kafka.Kafka /opt/kafka/config/server.properties

3.5. 从主题发送和接收信息

此流程描述了如何启动 Kafka 控制台制作者和消费者客户端,并使用它们发送和接收多个信息。

步骤 1 中会自动创建一个新主题。Topic auto-creation 使用 auto.create.topics.enable 配置属性(默认为 true )进行控制。另外,您可以在使用集群前配置和创建主题。如需更多信息,请参阅 主题

流程

  1. 启动 Kafka 控制台制作者,并将其配置为向新主题发送消息:

    /opt/kafka/bin/kafka-console-producer.sh --broker-list <bootstrap_address> --topic <topic-name>

    例如:

    /opt/kafka/bin/kafka-console-producer.sh --broker-list localhost:9092 --topic my-topic
  2. 在控制台中输入多个消息。按 Enter 键将每个单个信息发送到您的新主题:

    >message 1
    >message 2
    >message 3
    >message 4

    当 Kafka 自动创建新主题时,您可能会收到该主题不存在的警告:

    WARN Error while fetching metadata with correlation id 39 :
    {4-3-16-topic1=LEADER_NOT_AVAILABLE} (org.apache.kafka.clients.NetworkClient)

    在发送进一步的信息后,这个警告不应重新应用。

  3. 在新的终端窗口中,启动 Kafka 控制台消费者,并将其配置为从您的新主题开始读取消息。

    /opt/kafka/bin/kafka-console-consumer.sh --bootstrap-server <bootstrap_address> --topic <topic-name> --from-beginning

    例如:

    /opt/kafka/bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic my-topic --from-beginning

    传入消息显示在消费者控制台中。

  4. 切换到制作者控制台并发送其他信息。检查它们是否在消费者控制台中显示。
  5. 停止 Kafka 控制台制作者,然后按 Ctrl+C

3.6. 停止 AMQ Streams 服务

您可以通过运行脚本来停止 Kafka 和 ZooKeeper 服务。所有与 Kafka 和 ZooKeeper 服务的连接都将被终止。

先决条件

  • AMQ Streams 已安装在主机上
  • ZooKeeper 和 Kafka 已启动且正在运行

流程

  1. 停止 Kafka 代理。

    su - kafka
    /opt/kafka/bin/kafka-server-stop.sh
  2. 确认 Kafka 代理已停止。

    jcmd | grep kafka
  3. 停止 ZooKeeper。

    su - kafka
    /opt/kafka/bin/zookeeper-server-stop.sh

第 4 章 运行多节点环境

多节点环境由多个节点组成,它们作为集群运行。您可以使用复制 ZooKeeper 节点和代理节点集群,并在代理间复制主题。

多节点环境提供稳定性和可用性。

4.1. 运行多节点 ZooKeeper 集群

配置并运行 ZooKeeper 作为多节点集群。

先决条件

  • AMQ Streams 安装在所有将用作 ZooKeeper 集群节点的主机上。

运行集群

  1. /var/lib/zookeeper/ 中创建 myid 文件。为第一个 ZooKeeper 节点输入 ID 12 作为第二个 ZooKeeper 节点,以此类推。

    su - kafka
    echo "<NodeID>" > /var/lib/zookeeper/myid

    例如:

    su - kafka
    echo "1" > /var/lib/zookeeper/myid
  2. 编辑 ZooKeeper /opt/kafka/config/zookeeper.properties 配置文件:

    • 将选项 dataDir 设置为 /var/lib/zookeeper/
    • 配置 initLimitsyncLimit 选项。
    • 配置 reconfigEnabledstandaloneEnabled 选项。
    • 添加所有 ZooKeeper 节点的列表。该列表还应包含当前节点。

      具有五个成员的 ZooKeeper 集群节点配置示例

      tickTime=2000
      dataDir=/var/lib/zookeeper/
      initLimit=5
      syncLimit=2
      reconfigEnabled=true
      standaloneEnabled=false
      listener.security.protocol.map=PLAINTEXT:PLAINTEXT,REPLICATION:PLAINTEXT
      
      server.1=172.17.0.1:2888:3888:participant;172.17.0.1:2181
      server.2=172.17.0.2:2888:3888:participant;172.17.0.2:2181
      server.3=172.17.0.3:2888:3888:participant;172.17.0.3:2181
      server.4=172.17.0.4:2888:3888:participant;172.17.0.4:2181
      server.5=172.17.0.5:2888:3888:participant;172.17.0.5:2181

  3. 使用默认配置文件启动 ZooKeeper。

    su - kafka
    /opt/kafka/bin/zookeeper-server-start.sh -daemon /opt/kafka/config/zookeeper.properties
  4. 验证 ZooKeeper 是否正在运行。

    jcmd | grep zookeeper

    返回:

    number org.apache.zookeeper.server.quorum.QuorumPeerMain /opt/kafka/config/zookeeper.properties
  5. 在集群的所有节点上重复此步骤。
  6. 使用 ncat 实用程序向每个节点发送 stat 命令,来验证所有节点是否为集群的成员。

    使用 ncat stat 检查节点状态

    echo stat | ncat localhost 2181

    要使用四个字母单词命令,如 stat,您需要在 zookeeper.properties 中指定 4lw.commands.whitelist = the。

    输出显示节点可以是 leaderfollower

    ncat 命令的输出示例

    ZooKeeper version: 3.4.13-2d71af4dbe22557fda74f9a9b4309b15a7487f03, built on 06/29/2018 00:39 GMT
    Clients:
     /0:0:0:0:0:0:0:1:59726[0](queued=0,recved=1,sent=0)
    
    Latency min/avg/max: 0/0/0
    Received: 2
    Sent: 1
    Connections: 1
    Outstanding: 0
    Zxid: 0x200000000
    Mode: follower
    Node count: 4

4.2. 运行多节点 Kafka 集群

配置并运行 Kafka 作为多节点集群。

先决条件

运行集群

对于 AMQ Streams 集群中的每个 Kafka 代理:

  1. 编辑 /opt/kafka/config/server.properties Kafka 配置文件,如下所示:

    • 将第一个代理的 broker.id 字段设置为 0, 第二个代理为 1,以此类推。
    • zookeeper.connect 选项中配置连接到 ZooKeeper 的详情。
    • 配置 Kafka 侦听程序。
    • 设置提交日志应存储在 logs.dir 目录中的目录。

      在这里,我们看到 Kafka 代理的示例配置:

      broker.id=0
      zookeeper.connect=zoo1.my-domain.com:2181,zoo2.my-domain.com:2181,zoo3.my-domain.com:2181
      listeners=REPLICATION://:9091,PLAINTEXT://:9092
      listener.security.protocol.map=PLAINTEXT:PLAINTEXT,REPLICATION:PLAINTEXT
      inter.broker.listener.name=REPLICATION
      log.dirs=/var/lib/kafka

      在典型的安装中,每个 Kafka 代理在相同的硬件上运行,只有 broker.id 配置属性在每个代理配置间有所不同。

  2. 使用默认配置文件启动 Kafka 代理。

    su - kafka
    /opt/kafka/bin/kafka-server-start.sh -daemon /opt/kafka/config/server.properties
  3. 验证 Kafka 代理是否正在运行。

    jcmd | grep Kafka

    返回:

    number kafka.Kafka /opt/kafka/config/server.properties
  4. 使用 ncat 实用程序向其中一个 ZooKeeper 节点发送 dump 命令,来验证所有节点是否为 Kafka 集群的成员。

    使用 ncat dump 检查 ZooKeeper 中注册的所有 Kafka 代理

    echo dump | ncat zoo1.my-domain.com 2181

    要使用四个字母单词命令,如 dump,您需要在 zookeeper.properties 中指定 4lw.commands.whitelist = the。

    输出必须包含您刚才配置和启动的所有 Kafka 代理。

    带有 3 个节点的 Kafka 集群的 ncat 命令的输出示例

    SessionTracker dump:
    org.apache.zookeeper.server.quorum.LearnerSessionTracker@28848ab9
    ephemeral nodes dump:
    Sessions with Ephemerals (3):
    0x20000015dd00000:
            /brokers/ids/1
    0x10000015dc70000:
            /controller
            /brokers/ids/0
    0x10000015dc70001:
            /brokers/ids/2

4.3. 执行 Kafka 代理的安全滚动重启

此流程演示了如何在多节点集群中安全地滚动重启代理。在升级或更改 Kafka 集群配置属性后,通常需要滚动重启。

注意

有些代理配置不需要重启代理。如需更多信息,请参阅 Apache Kafka 文档中的 更新 代理配置。

执行代理重启后,检查请求相关主题分区,以确保副本分区已耗尽。

如果您要复制主题并确保至少一个副本处于同步状态,则只能执行安全重启,且不会丢失可用性。对于多节点集群,标准方法是具有最少为 3 的主题复制因素,并将最小 in-sync 副本设置为复制因素减 1。对于数据的持续时间,如果您在生成者配置中使用了 acks=all,在重新启动下一个代理前需要检查您重启的代理是否与所有它所同步的分区保持同步。

单节点集群在重启后不可用,因为所有分区都位于同一代理中。

先决条件

  • AMQ Streams 安装 在所有将用作 Kafka 代理的主机上。
  • 配置了 ZooKeeper 集群并运行
  • Kafka 集群按预期运行。

    检查未复制的分区或影响代理操作的任何其他问题。此流程中的步骤描述了如何检查不复制的分区。

流程

在每个 Kafka 代理上执行以下步骤。在继续执行下一个代理前,在第一个代理上完成这些步骤。在最后一个活跃控制器的代理上执行步骤。否则,活跃的控制器需要在多个重启时更改。

  1. 停止 Kafka 代理:

    /opt/kafka/bin/kafka-server-stop.sh
  2. 在完成后对需要重启的代理配置进行任何更改。

    如需更多信息,请参阅以下内容:

  3. 重启 Kafka 代理:

    /opt/kafka/bin/kafka-server-start.sh -daemon /opt/kafka/config/server.properties
  4. 检查 Kafka 是否正在运行:

    jcmd | grep kafka

    返回:

    number kafka.Kafka /opt/kafka/config/server.properties
  5. 使用 ncat 实用程序向其中一个 ZooKeeper 节点发送 dump 命令,来验证所有节点是否为 Kafka 集群的成员。

    使用 ncat dump 检查 ZooKeeper 中注册的所有 Kafka 代理

    echo dump | ncat zoo1.my-domain.com 2181

    要使用四个字母单词命令,如 dump,您需要在 zookeeper.properties 中指定 4lw.commands.whitelist = the。

    输出必须包含您启动的 Kafka 代理。

    带有 3 个节点的 Kafka 集群的 ncat 命令的输出示例

    SessionTracker dump:
    org.apache.zookeeper.server.quorum.LearnerSessionTracker@28848ab9
    ephemeral nodes dump:
    Sessions with Ephemerals (3):
    0x20000015dd00000:
            /brokers/ids/1
    0x10000015dc70000:
            /controller
            /brokers/ids/0
    0x10000015dc70001:
            /brokers/ids/2

  6. 等待直到代理有 0 个重复分区。您可以从命令行检查或使用指标。

    • 使用带有 --under-replicated-partitions 参数的 kafka-topics.sh 命令:

      /opt/kafka/bin/kafka-topics.sh --bootstrap-server <bootstrap_address>  --describe --under-replicated-partitions

      例如:

      /opt/kafka/bin/kafka-topics.sh --bootstrap-server localhost:9092 --describe --under-replicated-partitions

      命令提供了带有集群中复制分区的主题列表。

      带有复制分区的主题

      Topic: topic3 Partition: 4 Leader: 2 Replicas: 2,3 Isr: 2
      Topic: topic3 Partition: 5 Leader: 3 Replicas: 1,2 Isr: 1
      Topic: topic1 Partition: 1 Leader: 3 Replicas: 1,3 Isr: 3
      # …

      如果 ISR (同步副本)计数小于副本数,则会列出非复制分区。如果没有返回列表,则没有复制分区。

    • 使用 UnderReplicatedPartitions 指标:

      kafka.server:type=ReplicaManager,name=UnderReplicatedPartitions

      指标提供副本数,副本没有发现。您等到计数为零。

      提示

      当一个主题有一个或多个非复制分区时,请使用 Kafka Exporter 创建警报。

重启时检查日志

如果代理无法启动,请检查应用程序日志以了解更多信息。您还可以检查代理关闭的状态,并在 /opt/kafka/logs/server.log 应用程序日志中重启。

日志代理成功关闭

# ...
[2022-06-08 14:32:29,885] INFO Terminating process due to signal SIGTERM (org.apache.kafka.common.utils.LoggingSignalHandler)
[2022-06-08 14:32:29,886] INFO [KafkaServer id=0] shutting down (kafka.server.KafkaServer)
[2022-06-08 14:32:29,887] INFO [KafkaServer id=0] Starting controlled shutdown (kafka.server.KafkaServer)
[2022-06-08 14:32:29,896] INFO [KafkaServer id=0] Controlled shutdown request returned successfully after 6ms (kafka.server.KafkaServer)
# ...

记录成功重启代理

# ...
[2022-06-08 14:39:35,245] INFO [KafkaServer id=0] started (kafka.server.KafkaServer)
# ...

第 5 章 在 KRaft 模式下运行 Kafka (开发预览)

当您在 KRaft(Kafka Raft 元数据)模式下运行 AMQ Streams 时,Kafka 集群由控制器的内部仲裁而不是 ZooKeeper 进行管理。

Apache Kafka 处于对 ZooKeeper 的需求。KRaft 模式现在可以尝试。您可以在没有 ZooKeeper 的情况下以 KRaft 模式部署 Kafka 集群。

小心

KRaft 模式是实验性的,仅适用于 开发和测试,且不得在生产环境中启用。

目前,AMQ Streams 中的 KRaft 模式有以下主要限制:

  • 不支持从 ZooKeeper 移动到 KRaft 集群或其他方法。
  • 不支持 Apache Kafka 版本的升级和降级。
  • 不支持带有多个磁盘的 JBOD 存储。
  • 许多配置选项仍在开发中。

5.1. 在 KRaft 模式中使用 Kafka 的 AMQ Streams

如果您在 KRaft 模式中使用 Kafka,则不需要使用 ZooKeeper 进行集群协调或存储元数据。Kafka 使用作为控制器的代理协调集群本身。Kafka 还存储用于跟踪代理和分区状态的元数据。

要识别集群,请创建一个 ID。在为您添加到集群中的代理创建日志时使用 ID。

在每个代理节点配置中,指定以下内容:

  • 节点 ID
  • 代理角色
  • 用作控制器的代理( 投票)列表

代理执行代理、控制器或两者的角色。

代理角色
代理有时被称为节点或服务器,编配存储并传递信息。
控制器角色
控制器协调集群并管理跟踪元数据。

您可以使用组合代理和控制器节点,但您可能想要分离这些功能。在更简单的部署中,执行组合角色的代理可以更有效地。

您可以使用每个控制器的节点 ID 和连接详情(主机名和端口),指定配置为 voters 的控制器列表。

5.2. 以 KRaft 模式运行 Kafka 集群

在 KRaft 模式下运行 Kafka。如果您使用单节点或多节点 Kafka 集群,您可以在 KRaft 模式下运行 Kafka。至少运行三个代理和控制器节点以保持稳定性和可用性。

您可以为代理设置角色,以便它们也可以是控制器。您可以使用配置属性文件应用代理配置,包括角色的设置。代理配置因角色而异。KRaft 提供三个示例代理配置属性文件。

  • /opt/kafka/config/kraft/broker.properties 具有代理角色配置示例
  • /opt/kafka/config/kraft/controller.properties 具有控制器角色的示例配置
  • /opt/kafka/config/kraft/server.properties 具有双角色配置示例

您可以将代理配置基于这些示例属性文件。在此过程中,使用了示例 server.properties 配置。

先决条件

  • AMQ Streams 安装 在所有将用作 Kafka 代理的主机上。

流程

  1. 使用 kafka-storage 工具为 Kafka 集群生成 ID:

    /opt/kafka/bin/kafka-storage.sh random-uuid

    该命令返回一个 ID。KRaft 模式需要一个集群 ID。

  2. 为集群中的每个代理创建一个配置属性文件。

    您可以基于 Kafka 提供的示例上的文件。

    1. 将角色指定为 broker、'controllerbroker, controller

      例如,为双角色指定 process.roles=broker,为 controller 指定。

    2. 0 开始,为集群中的每个节点指定一个唯一 node.id

      例如,node.id=1

    3. 指定一个 controller.quorum.voters 列表,格式为 <node_id>@<hostname:port>

      例如,controller.quorum.voters=1@localhost:9093.

  3. 为 Kafka 集群中的每个节点设置日志目录:

    /opt/kafka/bin/kafka-storage.sh format -t <uuid> -c /opt/kafka/config/kraft/server.properties

    返回:

    Formatting /tmp/kraft-combined-logs

    <uuid > 替换为您生成的集群 ID。对集群中的每个节点使用相同的 ID。

    使用您为代理创建的属性文件应用代理配置。

    server.properties 配置文件中指定的默认日志目录位置为 /tmp/kraft-combined-logs。您可以添加以逗号分隔的列表来设置多个日志目录。

  4. 启动每个 Kafka 代理。

    /opt/kafka/bin/kafka-server-start.sh /opt/kafka/config/kraft/server.properties
  5. 检查 Kafka 是否正在运行:

    jcmd | grep kafka

    返回:

    number kafka.Kafka /opt/kafka/config/kraft/server.properties

现在,您可以创建主题,并从代理发送和接收信息。

对于传递消息的代理,您可以在集群中的代理间使用主题复制,以实现数据持久性。将主题配置为至少有三个复制因素,并将最小 in-sync 副本设置为复制因素的数量减 1。更多信息请参阅 第 7.7 节 “创建主题”

第 6 章 在 RHEL 部署中配置 AMQ Streams

使用 Kafka 和 ZooKeeper 属性文件来配置 AMQ Streams。

ZooKeeper
/kafka/config/zookeeper.properties
Kafka
/kafka/config/server.properties

属性文件是 Java 格式,每个属性位于一个独立的行中,使用一些格式:

<option> = <value>

#! 开头的行将被视为注释,将被 AMQ Streams 组件忽略。

# This is a comment

可以在新行 / carriage 返回前直接使用 \ 将值分成多行。

sasl.jaas.config=org.apache.kafka.common.security.plain.PlainLoginModule required \
    username="bob" \
    password="bobs-password";

在属性文件中保存更改后,您需要重启 Kafka 代理或 ZooKeeper。在多节点环境中,您需要在集群中的每个节点上重复这个过程。

6.1. 使用标准 Kafka 配置属性

使用标准 Kafka 配置属性配置 Kafka 组件。

属性提供控制和调优以下 Kafka 组件配置的选项:

  • 代理(Broker)
  • 主题
  • 客户端(生成者和消费者)
  • 管理客户端
  • Kafka Connect
  • Kafka Streams

代理和客户端参数包括配置授权、身份验证和加密的选项。

注意

对于 OpenShift 上的 AMQ Streams,一些配置属性完全由 AMQ Streams 管理,且无法更改。

有关 Kafka 配置属性以及如何使用属性调整部署的更多信息,请参阅以下指南:

6.2. 从环境变量加载配置值

使用 Environment Variables Configuration Provider 插件从环境变量加载配置数据。您可以使用 Environment Variables Configuration Provider,例如从环境变量加载证书或 JAAS 配置。

您可以使用供应商为所有 Kafka 组件加载配置数据,包括制作者和消费者。使用供应商,如为 Kafka Connect 连接器配置提供凭证。

先决条件

  • AMQ Streams 已下载并安装在主机上
  • 环境变量配置提供程序 JAR 文件

    JAR 文件可从 AMQ Streams 归档获得

流程

  1. 将 Environment Variables Configuration Provider JAR 文件添加到 Kafka libs 目录。
  2. 在 Kafka 组件的配置属性文件中初始化 Environment Variables Configuration Provider。例如,要初始化 Kafka 的供应商,请将配置添加到 server.properties 文件中。

    配置以启用环境变量配置提供程序

    config.providers=env
    config.providers.env.class=io.strimzi.kafka.EnvVarConfigProvider

  3. 将配置添加到属性文件中,以从环境变量加载数据。

    配置从环境变量加载数据

    option=${env:<MY_ENV_VAR_NAME>}

    使用大写或大写环境变量命名约定,如 MY_ENV_VAR_NAME

  4. 保存更改。
  5. 重启 Kafka 组件。

    有关在多节点集群中重启代理的详情,请参考 第 4.3 节 “执行 Kafka 代理的安全滚动重启”

6.3. 配置 ZooKeeper

Kafka 使用 ZooKeeper 来存储配置数据和集群协调。强烈建议运行复制 ZooKeeper 实例的集群。

6.3.1. 基本配置

最重要的 ZooKeeper 配置选项有:

tickTime
ZooKeeper 的基本时间单位(毫秒)。它用于心跳和会话超时。例如,最小会话超时将是两个 ticks。
dataDir
ZooKeeper 存储其事务日志和内存中数据库快照的目录。这应该设置为在安装过程中创建的 /var/lib/zookeeper/ 目录。
clientPort
客户端可以连接的端口号。默认值为 2181

名为 config/zookeeper.properties 的 ZooKeeper 配置文件示例位于 AMQ Streams 安装目录中。建议您将 dataDir 目录放在单独的磁盘设备中,以最小化 ZooKeeper 中的延迟。

zookeeper 配置文件应该位于 /opt/kafka/config/zookeeper.properties 中。配置文件的基本示例如下。该配置文件必须可以被 kafka 用户读取。

tickTime=2000
dataDir=/var/lib/zookeeper/
clientPort=2181

6.3.2. zookeeper 集群配置

在大多数生产环境中,我们建议您部署复制 ZooKeeper 实例的集群。对于可靠 ZooKeeper 服务运行,稳定且高度可用的 ZooKeeper 集群非常重要。ZooKeeper 集群也称为 ensembles

ZooKeeper 集群通常由奇数节点组成。ZooKeeper 要求集群中的大多数节点都已启动并运行。例如:

  • 在具有三个节点的集群中,至少两个节点必须已启动并在运行。这意味着,可以容忍一个节点停机。
  • 在由五个节点组成的集群中,必须至少有三个节点可用。这意味着,它可以容忍处于 down 的两个节点。
  • 在由 7 个节点组成的集群中,必须至少有四个节点可用。这意味着,它可以容忍要停机的三个节点。

在 ZooKeeper 集群中拥有更多节点可为整个集群提供更好的弹性和灵活性。

ZooKeeper 可以在带有偶数节点的集群中运行的集群中。但是,额外的节点不会增加集群的弹性。具有四个节点的集群需要至少三个节点可用,并且只能容忍一个节点处于 down 状态。因此,它具有与只有三个节点的集群相同的弹性。

理想情况下,不同的 ZooKeeper 节点应该位于不同的数据中心或网络段中。增加 ZooKeeper 节点数量会增加集群同步上花费的工作负载。对于大多数 Kafka 用例,带有 3、5 或 7 节点的 ZooKeeper 集群应该足够了。

警告

具有 3 个节点的 ZooKeeper 集群只能容忍 1 个不可用的节点。这意味着,如果在 ZooKeeper 集群的其他节点上进行维护,集群节点会崩溃。

重复的 ZooKeeper 配置支持独立配置支持所有配置选项。为集群配置添加了其他选项:

initLimit
允许遵循接收者连接到集群领导的时间长度。时间被指定为多个 ticks (更多详情请参阅 tickTime 选项 )。
syncLimit
遵循领导者的时间长度。时间被指定为多个 ticks (更多详情请参阅 tickTime 选项 )。
reconfigEnabled
启用或禁用动态重新配置。必须启用才能向 ZooKeeper 集群添加或删除服务器。
standaloneEnabled
启用或禁用独立模式,其中 ZooKeeper 只使用一个服务器运行。

除了以上选项外,每个配置文件应包含应该是 ZooKeeper 集群成员的服务器列表。服务器记录的格式应为 server.id=hostname:port1:port2,其中:

id
ZooKeeper 集群节点的 ID。
hostname
节点侦听连接的主机名或 IP 地址。
port1
用于集群内通信的端口号。
port2
用于领导选举机制的端口号。

以下是具有三个节点的 ZooKeeper 集群的示例配置文件:

tickTime=2000
dataDir=/var/lib/zookeeper/
initLimit=5
syncLimit=2
reconfigEnabled=true
standaloneEnabled=false

server.1=172.17.0.1:2888:3888:participant;172.17.0.1:2181
server.2=172.17.0.2:2888:3888:participant;172.17.0.2:2181
server.3=172.17.0.3:2888:3888:participant;172.17.0.3:2181
提示

要使用四个字母单词命令,在 zookeeper.properties 中指定 4lw.commands.whitelist=*

myid 文件

ZooKeeper 集群中的每个节点都必须被分配一个唯一 ID。每个节点的 ID 必须在 myid 文件中配置,并存储在 dataDir 文件夹中,如 /var/lib/zookeeper/myid 文件应仅包含一行,并将写入 ID 作为文本。ID 可以是从 1 到 255 的任何整数。您必须在每个集群节点上手动创建此文件。使用此文件,每个 ZooKeeper 实例都将使用来自配置文件中的对应 server. 行的配置来配置其监听程序。它还将使用所有其他 server. 行来识别其他集群成员。

在上例中,有三个节点,因此每个节点都有一个不同的 myid,值分别为 123

6.3.3. 身份验证

默认情况下,Kooa 不使用任何形式的身份验证,并允许匿名连接。但是,它支持 Java 认证和授权服务(JAAS),可用于使用简单身份验证和安全层 (SASL) 设置身份验证。ZooKeeper 支持使用带有本地存储凭证的 DIGEST-MD5 SASL 机制进行身份验证。

6.3.3.1. 使用 SASL 进行身份验证

JAAS 使用单独的配置文件进行配置。建议将 JAAS 配置文件放在与 ZooKeeper 配置相同的目录中(/opt/kafka/config/)。推荐的文件名是 zookeeper-jaas.conf。当使用具有多个节点的 ZooKeeper 集群时,必须在所有集群节点上创建 JAAS 配置文件。

JAAS 使用上下文进行配置。服务器和客户端等独立部分始终配置有单独的 上下文。该上下文是一个 配置选项,其格式如下:

ContextName {
       param1
       param2;
};

SASL 身份验证为服务器到服务器通信(实例 ZooKeeper 实例之间的沟通)和客户端到服务器通信( Kafka 和 ZooKeeper 之间相互通信)单独配置。服务器到服务器身份验证仅适用于具有多个节点的 ZooKeeper 集群。

服务器到服务器身份验证

对于服务器到服务器身份验证,HH 配置文件包含两个部分:

  • 服务器配置
  • 客户端配置

使用 DIGEST-MD5 SASL 机制时,QuorumServer 上下文用于配置身份验证服务器。它必须包含允许以未加密的形式与密码连接的所有用户名。第二个上下文 QuorumLearner 必须为内置在 ZooKeeper 中的客户端进行配置。它还包含未加密的形式的密码。DIGEST-MD5 机制的 JAAS 配置文件示例如下:

QuorumServer {
       org.apache.zookeeper.server.auth.DigestLoginModule required
       user_zookeeper="123456";
};

QuorumLearner {
       org.apache.zookeeper.server.auth.DigestLoginModule required
       username="zookeeper"
       password="123456";
};

除了 JAAS 配置文件外,还必须通过指定以下选项在常规 ZooKeeper 配置文件中启用 server-to-server 身份验证:

quorum.auth.enableSasl=true
quorum.auth.learnerRequireSasl=true
quorum.auth.serverRequireSasl=true
quorum.auth.learner.loginContext=QuorumLearner
quorum.auth.server.loginContext=QuorumServer
quorum.cnxn.threads.size=20

使用 KAFKA_OPTS 环境变量,将 JAAS 配置文件作为 Java 属性传递给 ZooKeeper 服务器:

su - kafka
export KAFKA_OPTS="-Djava.security.auth.login.config=/opt/kafka/config/zookeeper-jaas.conf"; /opt/kafka/bin/zookeeper-server-start.sh -daemon /opt/kafka/config/zookeeper.properties

有关服务器到服务器身份验证的更多信息,请参阅 ZooKeeper wiki

客户端到服务器身份验证

客户端到服务器身份验证配置在与服务器到服务器身份验证相同的 JAAS 文件中。但是,与 server-to-server 身份验证不同,它仅包含服务器配置。配置的客户端部分必须在客户端中进行。有关如何配置 Kafka 代理以使用身份验证连接到 ZooKeeper 的详情,请参考 Kafka 安装 部分。

将服务器上下文添加到 JAAS 配置文件中,以配置客户端到服务器身份验证。对于 DIGEST-MD5 机制,它会配置所有用户名和密码:

Server {
    org.apache.zookeeper.server.auth.DigestLoginModule required
    user_super="123456"
    user_kafka="123456"
    user_someoneelse="123456";
};

配置 JAAS 上下文后,通过添加以下行在 ZooKeeper 配置文件中启用客户端到服务器身份验证:

requireClientAuthScheme=sasl
authProvider.1=org.apache.zookeeper.server.auth.SASLAuthenticationProvider
authProvider.2=org.apache.zookeeper.server.auth.SASLAuthenticationProvider
authProvider.3=org.apache.zookeeper.server.auth.SASLAuthenticationProvider

您必须为每个作为 ZooKeeper 集群一部分的服务器添加 authProvider. <ID > 属性。

使用 KAFKA_OPTS 环境变量,将 JAAS 配置文件作为 Java 属性传递给 ZooKeeper 服务器:

su - kafka
export KAFKA_OPTS="-Djava.security.auth.login.config=/opt/kafka/config/zookeeper-jaas.conf"; /opt/kafka/bin/zookeeper-server-start.sh -daemon /opt/kafka/config/zookeeper.properties

有关在 Kafka 代理中配置 ZooKeeper 身份验证的更多信息,请参阅 第 6.4.5 节 “ZooKeeper 身份验证”

6.3.3.2. 使用 DIGEST-MD5 启用服务器到服务器身份验证

此流程描述了如何使用 ZooKeeper 集群节点间的 SASL DIGEST-MD5 机制启用身份验证。

先决条件

  • AMQ Streams 已安装在主机上
  • ZooKeeper 集群 配置了多个 节点。

启用 SASL DIGEST-MD5 身份验证

  1. 在所有 ZooKeeper 节点上,创建或编辑 /opt/kafka/config/zookeeper-jaas.conf JAAS 配置文件并添加以下上下文:

    QuorumServer {
           org.apache.zookeeper.server.auth.DigestLoginModule required
           user_<Username>="<Password>";
    };
    
    QuorumLearner {
           org.apache.zookeeper.server.auth.DigestLoginModule required
           username="<Username>"
           password="<Password>";
    };

    在 JAAS 上下文中,用户名和密码都必须相同。例如:

    QuorumServer {
           org.apache.zookeeper.server.auth.DigestLoginModule required
           user_zookeeper="123456";
    };
    
    QuorumLearner {
           org.apache.zookeeper.server.auth.DigestLoginModule required
           username="zookeeper"
           password="123456";
    };
  2. 在所有 ZooKeeper 节点上,编辑 /opt/kafka/config/zookeeper.properties ZooKeeper 配置文件并设置以下选项:

    quorum.auth.enableSasl=true
    quorum.auth.learnerRequireSasl=true
    quorum.auth.serverRequireSasl=true
    quorum.auth.learner.loginContext=QuorumLearner
    quorum.auth.server.loginContext=QuorumServer
    quorum.cnxn.threads.size=20
  3. 逐一重启所有 ZooKeeper 节点。要将 JAAS 配置传递给 ZooKeeper,请使用 KAFKA_OPTS 环境变量。

    su - kafka
    export KAFKA_OPTS="-Djava.security.auth.login.config=/opt/kafka/config/zookeeper-jaas.conf"; /opt/kafka/bin/zookeeper-server-start.sh -daemon /opt/kafka/config/zookeeper.properties

6.3.3.3. 使用 DIGEST-MD5 启用客户端到服务器身份验证

此流程描述了如何在 ZooKeeper 客户端和 ZooKeeper 之间使用 SASL DIGEST-MD5 机制启用身份验证。

先决条件

启用 SASL DIGEST-MD5 身份验证

  1. 在所有 ZooKeeper 节点上,创建或编辑 /opt/kafka/config/zookeeper-jaas.conf JAAS 配置文件并添加以下上下文:

    Server {
        org.apache.zookeeper.server.auth.DigestLoginModule required
        user_super="<SuperUserPassword>"
        user<Username1>_="<Password1>" user<USername2>_="<Password2>";
    };

    超级 自动具有管理员 priviledges。该文件可以包含多个用户,但 Kafka 代理只需要一个额外的用户。Kafka 用户的建议名称为 kafka

    以下示例显示了客户端 到服务器 身份验证的服务器上下文:

    Server {
        org.apache.zookeeper.server.auth.DigestLoginModule required
        user_super="123456"
        user_kafka="123456";
    };
  2. 在所有 ZooKeeper 节点上,编辑 /opt/kafka/config/zookeeper.properties ZooKeeper 配置文件并设置以下选项:

    requireClientAuthScheme=sasl
    authProvider.<IdOfBroker1>=org.apache.zookeeper.server.auth.SASLAuthenticationProvider
    authProvider.<IdOfBroker2>=org.apache.zookeeper.server.auth.SASLAuthenticationProvider
    authProvider.<IdOfBroker3>=org.apache.zookeeper.server.auth.SASLAuthenticationProvider

    必须为作为 ZooKeeper 集群一部分的每个节点添加 authProvider. <ID > 属性。三节点 ZooKeeper 集群配置示例必须类似如下:

    requireClientAuthScheme=sasl
    authProvider.1=org.apache.zookeeper.server.auth.SASLAuthenticationProvider
    authProvider.2=org.apache.zookeeper.server.auth.SASLAuthenticationProvider
    authProvider.3=org.apache.zookeeper.server.auth.SASLAuthenticationProvider
  3. 逐一重启所有 ZooKeeper 节点。要将 JAAS 配置传递给 ZooKeeper,请使用 KAFKA_OPTS 环境变量。

    su - kafka
    export KAFKA_OPTS="-Djava.security.auth.login.config=/opt/kafka/config/zookeeper-jaas.conf"; /opt/kafka/bin/zookeeper-server-start.sh -daemon /opt/kafka/config/zookeeper.properties

6.3.4. 授权

ZooKeeper 支持访问控制列表(ACL)来保护存储在其中的数据。Kafka 代理可以自动为他们创建的所有 ZooKeeper 记录配置 ACL 权限,因此没有其他 ZooKeeper 用户都可以修改它们。

有关在 Kafka 代理中启用 ZooKeeper ACL 的更多信息,请参阅 第 6.4.7 节 “ZooKeeper 授权”

6.3.5. TLS

ZooKeeper 支持 TLS 进行加密或身份验证。

6.3.6. 其他配置选项

您可以根据您的用例设置以下额外的 ZooKeeper 配置选项:

maxClientCnxns
到 ZooKeeper 集群的单个成员的最大并发客户端连接数。
autopurge.snapRetainCount
将保留 ZooKeeper 的内存中数据库的快照数量。默认值为 3
autopurge.purgeInterval
清除快照的时间间隔(以小时为单位)。默认值为 0, 这个选项被禁用。

所有可用的配置选项可在 ZooKeeper 文档 中找到。

6.4. 配置 Kafka

Kafka 使用属性文件来存储静态配置。配置文件的建议位置为 /opt/kafka/config/server.properties。该配置文件必须可以被 kafka 用户读取。

AMQ Streams 附带了一个示例配置文件,它突出显示了该产品的基本和高级功能。它可在 AMQ Streams 安装目录中的 config/server.properties 中找到。

本章解释了最重要的配置选项。

6.4.1. ZooKeeper

Kafka 代理需要 ZooKeeper 存储其配置的某些部分,并协调集群(例如,决定哪个节点是哪个分区的领导)。ZooKeeper 集群的连接详情存储在配置文件中。字段 zookeeper.connect 包含以逗号分隔的 zookeeper 集群成员的主机名和端口列表。

例如:

zookeeper.connect=zoo1.my-domain.com:2181,zoo2.my-domain.com:2181,zoo3.my-domain.com:2181

Kafka 将使用这些地址连接到 ZooKeeper 集群。使用这个配置,所有 Kafka znodes 将直接在 ZooKeeper 数据库的根目录中创建。因此,这样的 ZooKeeper 集群只能用于单个 Kafka 集群。要将多个 Kafka 集群配置为使用单个 ZooKeeper 集群,在 Kafka 配置文件中 ZooKeeper 连接字符串末尾指定基本(前缀)路径:

zookeeper.connect=zoo1.my-domain.com:2181,zoo2.my-domain.com:2181,zoo3.my-domain.com:2181/my-cluster-1

6.4.2. 监听器

监听器用于连接 Kafka 代理。每个 Kafka 代理都可以配置为使用多个监听程序。每个监听器都需要不同的配置,以便它可以在不同端口或网络接口上侦听。

要配置监听程序,请编辑配置文件中的 监听程序 属性(/opt/kafka/config/server.properties)。以逗号分隔列表在 监听程序 属性中添加监听程序。配置每个属性,如下所示:

<listenerName>://<hostname>:<port>

如果 <hostname> 为空,则 Kafka 将使用 java.net.InetAddress.getCanonicalHostName() 类作为主机名。

多个监听程序的配置示例

listeners=internal-1://:9092,internal-2://:9093,replication://:9094

当 Kafka 客户端连接到 Kafka 集群时,它首先连接到 bootstrap 服务器,这是集群节点之一。bootstrap 服务器为客户端提供集群中的所有代理列表,客户端分别连接到每个代理。代理列表基于配置 的监听程序

公告的监听程序

另外,您可以使用 advertised.listeners 属性为客户端提供不同于监听程序属性中给出的一系列不同的监听程序地址。如果其他网络基础架构(如代理)在客户端和代理之间,或者会使用外部 DNS 名称而不是 IP 地址,这很有用。

advertised.listeners 属性的格式方式与 listeners 属性相同。

公告的监听程序配置示例

listeners=internal-1://:9092,internal-2://:9093
advertised.listeners=internal-1://my-broker-1.my-domain.com:1234,internal-2://my-broker-1.my-domain.com:1235

注意

公告的监听程序的名称必须与监听程序属性中列出的名称匹配。

inter-broker 监听程序

inter-broker 侦听器 用于 Kafka 代理之间的通信。需要代理间通信才能:

  • 在不同代理间协调工作负载
  • 在不同代理中存储的分区间复制消息
  • 处理控制器中的管理任务,如分区领导更改

inter-broker 侦听器可以分配给您选择的端口。配置了多个监听程序时,您可以在 inter.broker.listener.name 属性中定义 inter-broker 侦听程序的名称。

在这里,内部代理侦听器被命名为 REPLICATION

listeners=REPLICATION://0.0.0.0:9091
inter.broker.listener.name=REPLICATION

control plane 监听程序

默认情况下,控制器和其他代理之间的通信使用 inter-broker 侦听器。控制器负责协调管理任务,如分区领导更改。

您可以为控制器连接启用专用 control plane 侦听程序。control plane 侦听器可以分配给您选择的端口。

要启用 control plane 侦听程序,请使用监听程序名称配置 control.plane.listener.name 属性:

listeners=CONTROLLER://0.0.0.0:9090,REPLICATION://0.0.0.0:9091
...
control.plane.listener.name=CONTROLLER

启用 control plane 侦听程序可能会提高集群性能,因为控制器通信不会因为代理中的数据复制不会延迟。数据复制通过 inter-broker 侦听程序继续进行。

如果没有配置 control.plane.listener,控制器连接将使用 inter-broker 侦听器

6.4.3. 提交日志

Apache Kafka 在提交日志中存储从制作者接收的所有记录。提交日志包含 Kafka 需要交付的实际数据,格式为记录。这些不是记录代理正在做什么的应用程序日志文件。

日志目录

您可以使用 log.dirs 属性文件配置日志目录,将提交日志存储在一个或多个日志目录中。它应该被设置为在安装过程中创建的 /var/lib/kafka 目录:

log.dirs=/var/lib/kafka

出于性能考虑,您可以将 log.dirs 配置为多个目录,并将其每个目录放在不同的物理设备中,以提高磁盘 I/O 性能。例如:

log.dirs=/var/lib/kafka1,/var/lib/kafka2,/var/lib/kafka3

6.4.4. 代理 ID

代理 ID 是集群中每个代理的唯一标识符。您可以分配一个大于或等于 0 的整数作为代理 ID。代理 ID 用于在重启或崩溃后识别代理,因此 id 稳定且不会随时间变化。代理 ID 在代理属性文件中配置:

broker.id=1

6.4.5. ZooKeeper 身份验证

默认情况下,Zooper 和 Kafka 之间的连接不会被身份验证。但是,Kafka 和 ZooKeeper 支持 Java 认证和授权服务(JAAS),可用于使用简单身份验证和安全层(SASL)设置身份验证。ZooKeeper 支持使用带有本地存储凭证的 DIGEST-MD5 SASL 机制进行身份验证。

6.4.5.1. JAAS 配置

ZooKeeper 连接的 SASL 身份验证必须在 JAAS 配置文件中配置。默认情况下,Kafka 将使用名为 Client 的 JAAS 上下文来连接到 ZooKeeper。客户端 上下文应该在 /opt/kafka/config/jass.conf 文件中配置。上下文必须启用 PLAIN SASL 身份验证,如下例所示:

Client {
    org.apache.kafka.common.security.plain.PlainLoginModule required
    username="kafka"
    password="123456";
};

6.4.5.2. 启用 ZooKeeper 身份验证

此流程描述了如何在连接到 ZooKeeper 时使用 SASL DIGEST-MD5 机制启用身份验证。

先决条件

启用 SASL DIGEST-MD5 身份验证

  1. 在所有 Kafka 代理节点上,创建或编辑 /opt/kafka/config/jaas.conf JAAS 配置文件并添加以下上下文:

    Client {
        org.apache.kafka.common.security.plain.PlainLoginModule required
        username="<Username>"
        password="<Password>";
    };

    用户名和密码应当与 ZooKeeper 中配置的名称相同。

    以下示例显示了 客户端 上下文:

    Client {
        org.apache.kafka.common.security.plain.PlainLoginModule required
        username="kafka"
        password="123456";
    };
  2. 逐一重启所有 Kafka 代理节点。要将 JAAS 配置传递给 Kafka 代理,请使用 KAFKA_OPTS 环境变量。

    su - kafka
    export KAFKA_OPTS="-Djava.security.auth.login.config=/opt/kafka/config/jaas.conf"; /opt/kafka/bin/kafka-server-start.sh -daemon /opt/kafka/config/server.properties

    有关在多节点集群中重启代理的详情,请参考 第 4.3 节 “执行 Kafka 代理的安全滚动重启”

其他资源

6.4.6. 授权

Kafka 代理中的授权使用授权器插件实现。

在本节中,我们将介绍如何使用 Kafka 提供的 AclAuthorizer 插件。

或者,您可以使用自己的授权插件。例如,如果您使用 基于 OAuth 2.0 令牌的身份验证,您可以使用 OAuth 2.0 授权

6.4.6.1. 简单 ACL 授权器

Authorizer 插件(包括 AclAuthorizer )通过 authorizer.class.name 属性启用:

authorizer.class.name=kafka.security.auth.AclAuthorizer

所选授权程序需要一个完全限定名称。对于 AclAuthorizer,完全限定名称为 kafka.security.auth.AclAuthorizer

6.4.6.1.1. ACL 规则

AclAuthorizer 使用 ACL 规则来管理对 Kafka 代理的访问。

ACL 规则以格式定义:

主体 P 允许/拒绝来自主机 H 的 Kafka 资源 R 中的操作 O

例如,可能会设置一个规则以便用户:

John 可以查看 主机 127.0.0.1的主题 注释

Host 是 John 进行连接的机器的 IP 地址。

在大多数情况下,用户是制作者或消费者应用程序:

Consumer01 可以对来自主机 127.0.0.1 的消费者组账户写入权限。

如果没有 ACL 规则

如果给定资源不存在 ACL 规则,则所有操作都会被拒绝。通过在 Kafka 配置文件 /opt/kafka/config/server.properties 中将属性 allow.everyone.if.no.acl.found 设置为 true 来更改此行为。

6.4.6.1.2. 主体

principal(主体)代表用户的身份。ID 的格式取决于客户端用来连接到 Kafka 的身份验证机制:

  • 用户:在没有身份验证的情况下连接时,ANONYMOUS
  • 使用简单身份验证机制(如 PLAIN 或 SCRAM)连接时,user:< username >。

    例如 User:admin or User:user1

  • 在使用 TLS 客户端身份验证连接时,user:& lt;DistinguishedName >。

    例如 User:CN=user1,O=MyCompany,L=Prague,C=CZ

  • 使用 Kerberos 连接时 user:<Kerberos username >。

DistinguishedName 是与客户端证书区分的名称。

Kerberos 用户名是 Kerberos 主体的主要部分,在使用 Kerberos 连接时默认使用。您可以使用 sasl.kerberos.principal.to.local.rules 属性来配置 Kafka 主体如何从 Kerberos 主体构建。

6.4.6.1.3. 用户身份验证

要使用授权,您需要启用并供您的客户端使用身份验证。否则,所有连接都将具有主体 用户:ANONYMOUS

有关身份验证方法的更多信息,请参阅 加密和验证

6.4.6.1.4. 超级用户

无论 ACL 规则是什么,超级用户都可以执行所有操作。

超级用户使用属性 super.users 在 Kafka 配置文件中定义。

例如:

super.users=User:admin,User:operator
6.4.6.1.5. 副本代理身份验证

启用授权后,它将适用于所有监听程序和所有连接。这包括用于在代理间复制数据的 inter-broker 连接。如果启用授权,请确保使用身份验证进行代理间的连接,并为代理提供足够权限。例如,如果代理之间的身份验证使用 kafka-broker 用户,则超级用户配置必须包含用户名 super.users=User:kafka-broker

6.4.6.1.6. 支持的资源

您可以将 Kafka ACL 应用到这些类型的资源:

  • 主题
  • 消费者组
  • 集群
  • TransactionId
  • DelegationToken
6.4.6.1.7. 支持的操作

AclAuthorizer 授权对资源的操作。

下表中带有 X 的字段标记每个资源支持的操作。

表 6.1. 资源支持的操作

 主题消费者组集群

X

X

 

X

  

创建

  

X

删除

X

  

更改

X

  

Describe

X

X

X

ClusterAction

  

X

All

X

X

X

6.4.6.1.8. ACL 管理选项

ACL 规则使用 bin/kafka-acls.sh 工具进行管理,该工具作为 Kafka 发行版本软件包的一部分提供。

使用 kafka-acls.sh 参数选项来添加、列出和删除 ACL 规则,以及执行其他功能。

参数需要双yphen 规范,如 --add

选项类型描述默认

add

操作

添加 ACL 规则。

 

remove

操作

删除 ACL 规则。

 

list

操作

列出 ACL 规则。

 

authorizer

操作

授权器的完全限定类名称。

kafka.security.auth.AclAuthorizer

authorizer-properties

Configuration

传递给授权器进行初始化的键/值对。

对于 AclAuthorizer,示例值为:zookeeper.connect=zoo1.my-domain.com:2181

 

bootstrap-server

资源

连接到 Kafka 集群的主机/端口对。

使用这个选项或 authorizer 选项,而不是同时使用这个选项。

command-config

资源

要传递给 Admin 客户端的配置属性文件,与 bootstrap-server 参数一起使用。

 

cluster

资源

将集群指定为 ACL 资源。

 

topic

资源

将主题名称指定为 ACL 资源。

用作通配符的星号(VirtualMachine),转换为 所有主题

单个命令可指定多个 --topic 选项。

 

group

资源

将消费者组名称指定为 ACL 资源。

单个命令可指定多个 --group 选项。

 

transactional-id

资源

指定事务 ID 作为 ACL 资源。

事务交付意味着,生成者向多个分区发送的所有消息都必须成功交付或不提供。

使用通配符星号 (*) 代表所有 ID

 

delegation-token

资源

将委派令牌指定为 ACL 资源。

使用通配符星号 (*) 代表所有令牌

 

resource-pattern-type

Configuration

指定 add 参数的资源模式,或为 listremove 参数指定资源模式过滤器值。

使用 literalprefixed 作为一个资源名称的资源特征类型。

使用 anymatch 作为资源模式过滤器值或特定的模式类型过滤器。

literal

allow-principal

主体

添加到允许 ACL 规则中的主体。

单个命令可指定多个 --allow-principal 选项。

 

deny-principal

主体

添加到拒绝 ACL 规则中的主体。

单个命令可指定多个 --deny-principal 选项。

 

主体

主体

list 参数一起使用的主体名称,用于返回主体的 ACL 列表。

单个命令可指定多个 --principal 选项。

 

allow-host

主机

允许访问 --allow-principal 中列出的主体的 IP 地址。

不支持主机名或 CIDR 范围。

如果指定了 --allow-principal,则默认为 * 代表"所有主机"。

deny-host

主机

拒绝访问 --deny-principal 中列出的主体的 IP 地址。

不支持主机名或 CIDR 范围。

如果指定了 --deny-principal,则默认为 * 代表"所有主机"。

operation

操作

允许或拒绝操作。

可在单个命令中指定多个Multiple --operation 选项。

All

producer

快捷键

允许或拒绝消息制作者需要的所有操作的快捷方式(主题中为 WRITE 和 DESCRIBE,集群中为 CREATE)。

 

consumer

快捷键

允许或拒绝消息消费者所需的所有操作的快捷方式(READ 和 DESCRIBE on topic, READ on consumer group)。

 

idempotent

快捷键

--producer 参数一起使用时启用 idempotence 的快捷方式,以便消息会完全传送到分区。

如果制作者被授权根据特定事务 ID 发送消息,则会自动启用 Idepmotence。

 

force

快捷键

接受所有查询且不提示的快捷方式。

 

6.4.6.2. 启用授权

此流程描述了如何在 Kafka 代理中为授权启用 AclAuthorizer 插件。

先决条件

流程

  1. 编辑 /opt/kafka/config/server.properties Kafka 配置文件,以使用 AclAuthorizer

    authorizer.class.name=kafka.security.auth.AclAuthorizer
  2. (重新)启动 Kafka 代理。

6.4.6.3. 添加 ACL 规则

当使用 AclAuthorizer 插件根据访问控制列表(ACL)控制对 Kafka 代理的访问时,您可以使用 kafka-acls.sh 工具添加新的 ACL 规则。

先决条件

流程

  • 使用 --add 选项运行 kafka-acls.sh

    示例:

  • 允许使用 MyConsumerGroup 消费者组从 myTopic 读取 user1user2 访问权限。

    opt/kafka/bin/kafka-acls.sh --bootstrap-server localhost:9092 --add --operation Read --topic myTopic --allow-principal User:user1 --allow-principal User:user2
    
    opt/kafka/bin/kafka-acls.sh --bootstrap-server localhost:9092 --add --operation Describe --topic myTopic --allow-principal User:user1 --allow-principal User:user2
    
    opt/kafka/bin/kafka-acls.sh --bootstrap-server localhost:9092 --add --operation Read --operation Describe --group MyConsumerGroup --allow-principal User:user1 --allow-principal User:user2
  • 拒绝 user1 从 IP 地址主机 127.0.0.1 读取 myTopic

    opt/kafka/bin/kafka-acls.sh --bootstrap-server localhost:9092 --add --operation Describe --operation Read --topic myTopic --group MyConsumerGroup --deny-principal User:user1 --deny-host 127.0.0.1
  • 添加 user1 作为带有 MyConsumerGroupmyTopic 的消费者。

    opt/kafka/bin/kafka-acls.sh --bootstrap-server localhost:9092 --add --consumer --topic myTopic --group MyConsumerGroup --allow-principal User:user1

其他资源

6.4.6.4. 列出 ACL 规则

当使用 AclAuthorizer 插件根据访问控制列表(ACL)控制对 Kafka 代理的访问时,您可以使用 kafka-acls.sh 实用程序列出现有的 ACL 规则。

先决条件

流程

  • 使用 --list 选项运行 kafka-acls.sh

    例如:

    opt/kafka/bin/kafka-acls.sh --bootstrap-server localhost:9092 --list --topic myTopic
    
    Current ACLs for resource `Topic:myTopic`:
    
    User:user1 has Allow permission for operations: Read from hosts: *
    User:user2 has Allow permission for operations: Read from hosts: *
    User:user2 has Deny permission for operations: Read from hosts: 127.0.0.1
    User:user1 has Allow permission for operations: Describe from hosts: *
    User:user2 has Allow permission for operations: Describe from hosts: *
    User:user2 has Deny permission for operations: Describe from hosts: 127.0.0.1

其他资源

6.4.6.5. 删除 ACL 规则

当使用 AclAuthorizer 插件根据访问控制列表(ACL)控制对 Kafka 代理的访问时,您可以使用 kafka-acls.sh 工具删除现有 ACL 规则。

先决条件

流程

  • 使用 --remove 选项运行 kafka-acls.sh

    示例:

  • 删除 ACL,允许 user1user2 使用 MyConsumerGroup 消费者组从 myTopic 读取。

    opt/kafka/bin/kafka-acls.sh --bootstrap-server localhost:9092 --remove --operation Read --topic myTopic --allow-principal User:user1 --allow-principal User:user2
    
    opt/kafka/bin/kafka-acls.sh --bootstrap-server localhost:9092 --remove --operation Describe --topic myTopic --allow-principal User:user1 --allow-principal User:user2
    
    opt/kafka/bin/kafka-acls.sh --bootstrap-server localhost:9092 --remove --operation Read --operation Describe --group MyConsumerGroup --allow-principal User:user1 --allow-principal User:user2
  • 删除 ACL 添加 user1 作为带有 MyConsumerGroupmyTopic 的消费者。

    opt/kafka/bin/kafka-acls.sh --bootstrap-server localhost:9092 --remove --consumer --topic myTopic --group MyConsumerGroup --allow-principal User:user1
  • 删除 ACL 拒绝 user1 访问权限,以从 IP 地址主机 127.0.0.1 读取 myTopic

    opt/kafka/bin/kafka-acls.sh --bootstrap-server localhost:9092 --remove --operation Describe --operation Read --topic myTopic --group MyConsumerGroup --deny-principal User:user1 --deny-host 127.0.0.1

其他资源

6.4.7. ZooKeeper 授权

当在 Kafka 和 ZooKeeper 之间启用身份验证时,您可以使用 ZooKeeper 访问控制列表(ACL)规则自动控制对存储在 ZooKeeper 中的 Kafka 元数据的访问。

6.4.7.1. ACL 配置

ZooKeeper ACL 规则的强制由 config/server.properties Kafka 配置文件中的 zookeeper.set.acl 属性控制。

这个属性默认为禁用,并通过设置为 true 来启用:

zookeeper.set.acl=true

如果启用了 ACL 规则,当在 ZooKeeper 中创建 znode 时,只有创建它的 Kafka 用户才可以修改或删除它。所有其他用户都具有只读访问权限。

Kafka 仅为新创建的 ZooKeeper znodes 设置 ACL 规则。如果仅在集群首次启动后启用 ACL,zookeeper-security-migration.sh 工具可以在所有现有 znodes 上设置 ACL。

ZooKeeper 中数据的保密性

存储在 ZooKeeper 中的数据包括:

  • 主题名称及其配置
  • 使用 SASL SCRAM 身份验证时,Salted 和散列用户凭证。

但是 ZooKeeper 不会存储使用 Kafka 发送和接收的任何记录。存储在 ZooKeeper 中的数据假定是非机密的。

如果数据被视为机密(例如,由于主题名称包含客户 ID),则唯一可用于保护的选项是隔离网络级别的 ZooKeeper,仅允许访问 Kafka 代理。

6.4.7.2. 为新 Kafka 集群启用 ZooKeeper ACL

此流程描述了如何在 Kafka 配置中为新的 Kafka 集群启用 ZooKeeper ACL。仅在 Kafka 集群首次启动前使用此流程。有关在已在运行的集群中启用 ZooKeeper ACL,请参阅 第 6.4.7.3 节 “在现有 Kafka 集群中启用 ZooKeeper ACL”

先决条件

  • AMQ Streams 安装 在所有将用作 Kafka 代理的主机上。
  • ZooKeeper 集群 已配置并运行
  • 在 ZooKeeper 中启用了 客户端到服务器身份验证。
  • 在 Kafka 代理中,ZooKeeper 身份验证被启用
  • Kafka 代理尚未启动。

流程

  1. 编辑 /opt/kafka/config/server.properties Kafka 配置文件,在所有集群节点上将 zookeeper.set.acl 字段设置为 true

    zookeeper.set.acl=true
  2. 启动 Kafka 代理。

6.4.7.3. 在现有 Kafka 集群中启用 ZooKeeper ACL

此流程描述了如何在 Kafka 配置中为正在运行的 Kafka 集群启用 ZooKeeper ACL。使用 zookeeper-security-migration.sh 工具,在所有存在的 znodes 中设置 ZooKeeper ACL。zookeeper-security-migration.sh 可作为 AMQ Streams 的一部分,并可在 bin 目录中找到。

先决条件

启用 ZooKeeper ACL

  1. 编辑 /opt/kafka/config/server.properties Kafka 配置文件,在所有集群节点上将 zookeeper.set.acl 字段设置为 true

    zookeeper.set.acl=true
  2. 逐一重启所有 Kafka 代理。

    有关在多节点集群中重启代理的详情,请参考 第 4.3 节 “执行 Kafka 代理的安全滚动重启”

  3. 使用 zookeeper-security-migration.sh 工具在所有现有 ZooKeeper znodes 中设置 ACL。

    su - kafka
    cd /opt/kafka
    KAFKA_OPTS="-Djava.security.auth.login.config=./config/jaas.conf"; ./bin/zookeeper-security-migration.sh --zookeeper.acl=secure --zookeeper.connect=<ZooKeeperURL>
    exit

    例如:

    su - kafka
    cd /opt/kafka
    KAFKA_OPTS="-Djava.security.auth.login.config=./config/jaas.conf"; ./bin/zookeeper-security-migration.sh --zookeeper.acl=secure --zookeeper.connect=zoo1.my-domain.com:2181
    exit

6.4.8. 加密和验证

AMQ Streams 支持加密和验证,它们被配置为监听程序配置的一部分。

6.4.8.1. 侦听器配置

Kafka 代理中的加密和身份验证为每个监听程序配置。有关 Kafka 侦听器配置的更多信息,请参阅 第 6.4.2 节 “监听器”

Kafka 代理中的每个监听程序都使用自己的安全协议进行配置。配置属性 listener.security.protocol.map 定义哪个监听程序使用哪个安全协议。它将每个监听程序名称映射到其安全协议。支持的安全协议有:

明文
没有加密或身份验证的监听程序。
SSL
使用 TLS 加密(可选)使用 TLS 客户端证书进行身份验证的监听程序。
SASL_PLAINTEXT
没有加密的监听程序,但使用基于 SASL 的身份验证。
SASL_SSL
使用基于 TLS 的加密和基于 SASL 的身份验证的监听程序。

根据以下 监听程序配置

listeners=INT1://:9092,INT2://:9093,REPLICATION://:9094

listener.security.protocol.map 可能如下所示:

listener.security.protocol.map=INT1:SASL_PLAINTEXT,INT2:SASL_SSL,REPLICATION:SSL

这会将监听器 INT1 配置为使用 SASL 身份验证的未加密的连接,监听程序 INT2 使用带有 SASL 身份验证的加密连接,以及 REPLICATION 接口以使用 TLS 加密(可能通过 TLS 客户端身份验证)。相同的安全协议可以多次使用。以下示例也是有效的配置:

listener.security.protocol.map=INT1:SSL,INT2:SSL,REPLICATION:SSL

这样的配置将对所有接口使用 TLS 加密和 TLS 身份验证。以下章节将详细介绍如何配置 TLS 和 SASL。

6.4.8.2. TLS 加密

Kafka 支持 TLS 来加密与 Kafka 客户端的通信。

要使用 TLS 加密和服务器身份验证,必须提供包含私钥和公钥的密钥存储。这通常使用 Java Keystore (JKS)格式的文件来完成。在 ssl.keystore.location 属性中设置到这个文件的路径。应使用 ssl.keystore.password 属性来设置保护密钥存储的密码。例如:

ssl.keystore.location=/path/to/keystore/server-1.jks
ssl.keystore.password=123456

在某些情况下,会使用额外的密码来保护私钥。任何此类密码都可以使用 ssl.key.password 属性进行设置。

Kafka 可以使用由证书颁发机构和自签名密钥签名的密钥。使用由证书颁发机构签名的密钥应始终是首选的方法。为了允许客户端验证其正在连接的 Kafka 代理的身份,证书应始终包含公告的主机名 (CN) 或 Subject Alternative Name(SAN)。

对于不同的监听程序,可以使用不同的 SSL 配置。所有以 ssl. 开头的选项都可以以 listener.name.<NameOf TheListener > 前缀,其中监听器的名称必须总是在小写中。这将覆盖该特定监听器的默认 SSL 配置。以下示例演示了如何为不同的监听程序使用不同的 SSL 配置:

listeners=INT1://:9092,INT2://:9093,REPLICATION://:9094
listener.security.protocol.map=INT1:SSL,INT2:SSL,REPLICATION:SSL

# Default configuration - will be used for listeners INT1 and INT2
ssl.keystore.location=/path/to/keystore/server-1.jks
ssl.keystore.password=123456

# Different configuration for listener REPLICATION
listener.name.replication.ssl.keystore.location=/path/to/keystore/server-1.jks
listener.name.replication.ssl.keystore.password=123456

其他 TLS 配置选项

除了上面描述的主要 TLS 配置选项外,Kafka 还支持很多选项来微调 TLS 配置。例如,要启用或禁用 TLS / SSL 协议或密码套件:

ssl.cipher.suites
启用的密码套件列表。每个密码套件都是用于 TLS 连接的身份验证、加密、MAC 和密钥交换算法的组合。默认情况下启用所有可用的密码套件。
ssl.enabled.protocols
启用的 TLS / SSL 协议列表。默认为 TLSv1.2,TLSv1.1,TLSv1

6.4.8.3. 启用 TLS 加密

这个步骤描述了如何在 Kafka 代理中启用加密。

先决条件

  • AMQ Streams 安装 在所有将用作 Kafka 代理的主机上。

流程

  1. 为集群中的所有 Kafka 代理生成 TLS 证书。证书应在其通用名称或主题备用名称中公告和 bootstrap 地址。
  2. 编辑所有集群节点上的 /opt/kafka/config/server.properties Kafka 配置文件:

    • 更改 listener.security.protocol.map 字段,为您要使用 TLS 加密的监听程序指定 SSL 协议。
    • 使用代理证书将 ssl.keystore.location 选项设置为 JKS 密钥存储的路径。
    • ssl.keystore.password 选项设置为您用来保护密钥存储的密码。

      例如:

      listeners=UNENCRYPTED://:9092,ENCRYPTED://:9093,REPLICATION://:9094
      listener.security.protocol.map=UNENCRYPTED:PLAINTEXT,ENCRYPTED:SSL,REPLICATION:PLAINTEXT
      ssl.keystore.location=/path/to/keystore/server-1.jks
      ssl.keystore.password=123456
  3. (重新)启动 Kafka 代理

6.4.8.4. 身份验证

要进行身份验证,您可以使用:

6.4.8.4.1. TLS 客户端身份验证

TLS 客户端身份验证只能用于已经使用 TLS 加密的连接。要使用 TLS 客户端身份验证,可以为代理提供带有公钥的信任存储。这些密钥可用于验证连接到代理的客户端。信任存储应该以 Java Keystore (JKS)格式提供,并且应包含证书颁发机构的公钥。所有由信任存储中包含的认证机构签名的公钥和私钥的客户端都会被身份验证。信任存储的位置使用字段 ssl.truststore.location 设置。如果信任存储受密码保护,则应在 ssl.truststore.password 属性中设置密码。例如:

ssl.truststore.location=/path/to/keystore/server-1.jks
ssl.truststore.password=123456

配置信任存储后,必须使用 ssl.client.auth 属性启用 TLS 客户端身份验证。此属性可设置为三个不同值之一:

none
TLS 客户端身份验证已关闭。(默认值)
requested
TLS 客户端身份验证是可选的。客户端将被要求使用 TLS 客户端证书进行身份验证,但可以选择不使用它们。
required
需要客户端才能使用 TLS 客户端证书进行身份验证。

当客户端使用 TLS 客户端身份验证进行身份验证时,经过身份验证的主体名称是与经过身份验证的客户端证书区分名称。例如,具有可分辨名称 CN=someuser 的证书的用户将使用以下主体 CN=someuser,OU=Unknown,O=Unknown,L=Unknown,ST=Unknown,C=Unknown,C=Unknown 进行验证。如果没有使用 TLS 客户端身份验证并禁用 SASL,则主体名称为 ANONYMOUS

6.4.8.4.2. SASL 身份验证

SASL 身份验证使用 Java 身份验证和授权服务(JAAS)进行配置。JAAS 还用于在 Kafka 和 ZooKeeper 之间验证连接。JAAS 使用自己的配置文件。此文件的建议位置为 /opt/kafka/config/jaas.conf。该文件必须可以被 kafka 用户读取。在运行 Kafka 时,使用 Java 系统属性 java.security.auth.login.config 来指定此文件的位置。启动代理节点时,必须将此属性传递给 Kafka:

KAFKA_OPTS="-Djava.security.auth.login.config=/path/to/my/jaas.config"; bin/kafka-server-start.sh

通过普通未加密的连接以及 TLS 连接支持 SASL 身份验证。SASL 可以为每个监听器单独启用。要启用它,listener.security.protocol.map 中的安全协议必须是 SASL_PLAINTEXTSASL_SSL

Kafka 中的 SASL 身份验证支持几种不同的机制:

PLAIN
根据用户名和密码实施身份验证。用户名和密码存储在 Kafka 配置中。
SCRAM-SHA-256SCRAM-SHA-512
使用 Salted Challenge Response Authentication Mechanism (SCRAM) 实现验证。SCRAM 凭证集中存储在 ZooKeeper 中。当 ZooKeeper 集群节点在专用网络中运行隔离的情况,可以使用 SCRAM。
GSSAPI
针对 Kerberos 服务器实施身份验证。
警告

PLAIN 机制以未加密的格式通过网络发送用户名和密码。因此,它应该只与 TLS 加密结合使用。

SASL 机制通过 JAAS 配置文件配置。Kafka 使用名为 KafkaServer 的 JAAS 上下文。在 JAAS 中配置后,必须在 Kafka 配置中启用 SASL 机制。这可以通过 sasl.enabled.mechanisms 属性来完成。此属性包含以逗号分隔的启用机制列表:

sasl.enabled.mechanisms=PLAIN,SCRAM-SHA-256,SCRAM-SHA-512

如果用于 inter-broker 通信的监听程序使用 SASL,则必须使用属性 sasl.mechanism.inter.broker.protocol 指定它应使用的 SASL 机制。例如:

sasl.mechanism.inter.broker.protocol=PLAIN

将用于 openshift-broker 通信的用户名和密码,该通信必须使用字段 usernamepasswordKafkaServer JAAS 上下文中指定。

SASL PLAIN

要使用 PLAIN 机制,允许连接的用户名和密码直接在 JAAS 上下文中指定。以下示例显示了为 SASL PLAIN 身份验证配置的上下文。这个示例配置三个不同的用户:

  • admin
  • user1
  • user2
KafkaServer {
    org.apache.kafka.common.security.plain.PlainLoginModule required
    user_admin="123456"
    user_user1="123456"
    user_user2="123456";
};

与用户数据库的 JAAS 配置文件应保持在所有 Kafka 代理上同步。

当 SASL PLAIN 也用于内部代理身份验证时,usernamepassword 属性应包含在 JAAS 上下文中:

KafkaServer {
    org.apache.kafka.common.security.plain.PlainLoginModule required
    username="admin"
    password="123456"
    user_admin="123456"
    user_user1="123456"
    user_user2="123456";
};

SASL SCRAM

Kafka 中的 SCRAM 身份验证由两个机制组成: SCRAM-SHA-256SCRAM-SHA-512。这些机制只在使用的哈希算法中有所不同 - SHA-256 与更强大的 SHA-512 相比。要启用 SCRAM 身份验证,HMQ 配置文件必须包括以下配置:

KafkaServer {
    org.apache.kafka.common.security.scram.ScramLoginModule required;
};

当在 Kafka 配置文件中启用 SASL 身份验证时,可以同时列出 SCRAM 机制。但是,只能为代理间通信选择一个。例如:

sasl.enabled.mechanisms=SCRAM-SHA-256,SCRAM-SHA-512
sasl.mechanism.inter.broker.protocol=SCRAM-SHA-512

SCRAM 机制的用户凭证存储在 ZooKeeper 中。kafka-configs.sh 工具可用于管理它们。例如,运行以下命令添加用户 user1,密码为 123456 :

bin/kafka-configs.sh --bootstrap-server localhost:9092 --alter --add-config 'SCRAM-SHA-256=[password=123456],SCRAM-SHA-512=[password=123456]' --entity-type users --entity-name user1

要删除用户凭证,请使用:

bin/kafka-configs.sh --bootstrap-server localhost:9092 --alter --delete-config 'SCRAM-SHA-512' --entity-type users --entity-name user1

SASL GSSAPI

用于使用 Kerberos 进行身份验证的 SASL 机制称为 GSSAPI。要配置 Kerberos SASL 身份验证,应将以下配置添加到 JAAS 配置文件中:

KafkaServer {
    com.sun.security.auth.module.Krb5LoginModule required
    useKeyTab=true
    storeKey=true
    keyTab="/etc/security/keytabs/kafka_server.keytab"
    principal="kafka/kafka1.hostname.com@EXAMPLE.COM";
};

Kerberos 主体中的域名必须始终为大写。

除了 JAAS 配置外,还需要在 Kafka 配置中的 sasl.kerberos.service.name 属性中指定 Kerberos 服务名称:

sasl.enabled.mechanisms=GSSAPI
sasl.mechanism.inter.broker.protocol=GSSAPI
sasl.kerberos.service.name=kafka

多个 SASL 机制

Kafka 可以同时使用多个 SASL 机制。不同的 JAAS 配置都可以添加到同一上下文中:

KafkaServer {
    org.apache.kafka.common.security.plain.PlainLoginModule required
    user_admin="123456"
    user_user1="123456"
    user_user2="123456";

    com.sun.security.auth.module.Krb5LoginModule required
    useKeyTab=true
    storeKey=true
    keyTab="/etc/security/keytabs/kafka_server.keytab"
    principal="kafka/kafka1.hostname.com@EXAMPLE.COM";

    org.apache.kafka.common.security.scram.ScramLoginModule required;
};

启用多个机制时,客户端将能够选择想要使用的机制。

6.4.8.5. 启用 TLS 客户端身份验证

这个步骤描述了如何在 Kafka 代理中启用 TLS 客户端身份验证。

先决条件

  • AMQ Streams 安装 在所有将用作 Kafka 代理的主机上。
  • 启用 TLS 加密。

流程

  1. 准备包含用于签署用户证书的证书颁发机构的公钥的 JKS 信任存储。
  2. 编辑所有集群节点上的 /opt/kafka/config/server.properties Kafka 配置文件:

    • 使用用户证书的证书颁发机构,将 ssl.truststore.location 选项设置为 JKS 信任存储的路径。
    • ssl.truststore.password 选项设置为您用来保护信任存储的密码。
    • ssl.client.auth 选项设置为 required

      例如:

      ssl.truststore.location=/path/to/truststore.jks
      ssl.truststore.password=123456
      ssl.client.auth=required
  3. (重新)启动 Kafka 代理

6.4.8.6. 启用 SASL PLAIN 身份验证

这个步骤描述了如何在 Kafka 代理中启用 SASL PLAIN 身份验证。

先决条件

  • AMQ Streams 安装 在所有将用作 Kafka 代理的主机上。

流程

  1. 编辑或创建 /opt/kafka/config/jaas.conf JAAS 配置文件。此文件应包含您的所有用户及其密码。在所有 Kafka 代理中确保此文件都相同。

    例如:

    KafkaServer {
        org.apache.kafka.common.security.plain.PlainLoginModule required
        user_admin="123456"
        user_user1="123456"
        user_user2="123456";
    };
  2. 编辑所有集群节点上的 /opt/kafka/config/server.properties Kafka 配置文件:

    • 更改 listener.security.protocol.map 字段,为您要使用 SASL PLAIN 身份验证的监听程序指定 SASL_PLAINTEXTSASL_SSL 协议。
    • sasl.enabled.mechanisms 选项设置为 PLAIN

      例如:

      listeners=INSECURE://:9092,AUTHENTICATED://:9093,REPLICATION://:9094
      listener.security.protocol.map=INSECURE:PLAINTEXT,AUTHENTICATED:SASL_PLAINTEXT,REPLICATION:PLAINTEXT
      sasl.enabled.mechanisms=PLAIN
  3. 使用 KAFKA_OPTS 环境变量(重新)启动 Kafka 代理,将 JAAS 配置传递给 Kafka 代理。

    su - kafka
    export KAFKA_OPTS="-Djava.security.auth.login.config=/opt/kafka/config/jaas.conf"; /opt/kafka/bin/kafka-server-start.sh -daemon /opt/kafka/config/server.properties

6.4.8.7. 启用 SASL SCRAM 身份验证

这个步骤描述了如何在 Kafka 代理中启用 SASL SCRAM 身份验证。

先决条件

  • AMQ Streams 安装 在所有将用作 Kafka 代理的主机上。

流程

  1. 编辑或创建 /opt/kafka/config/jaas.conf JAAS 配置文件。为 KafkaServer 上下文启用 ScramLoginModule。在所有 Kafka 代理中确保此文件都相同。

    例如:

    KafkaServer {
        org.apache.kafka.common.security.scram.ScramLoginModule required;
    };
  2. 编辑所有集群节点上的 /opt/kafka/config/server.properties Kafka 配置文件:

    • 更改 listener.security.protocol.map 字段,为您要使用 SASL SCRAM 身份验证的监听程序指定 SASL_PLAINTEXTSASL_SSL 协议。
    • sasl.enabled.mechanisms 选项设置为 SCRAM-SHA-256SCRAM-SHA-512

      例如:

      listeners=INSECURE://:9092,AUTHENTICATED://:9093,REPLICATION://:9094
      listener.security.protocol.map=INSECURE:PLAINTEXT,AUTHENTICATED:SASL_PLAINTEXT,REPLICATION:PLAINTEXT
      sasl.enabled.mechanisms=SCRAM-SHA-512
  3. 使用 KAFKA_OPTS 环境变量(重新)启动 Kafka 代理,将 JAAS 配置传递给 Kafka 代理。

    su - kafka
    export KAFKA_OPTS="-Djava.security.auth.login.config=/opt/kafka/config/jaas.conf"; /opt/kafka/bin/kafka-server-start.sh -daemon /opt/kafka/config/server.properties

6.4.8.8. 添加 SASL SCRAM 用户

这个步骤描述了如何使用 SASL SCRAM 添加新用户进行身份验证。

先决条件

  • AMQ Streams 安装 在所有将用作 Kafka 代理的主机上。
  • 启用 SASL SCRAM 身份验证。

流程

  • 使用 kafka-configs.sh 工具添加新的 SASL SCRAM 用户。

    bin/kafka-configs.sh --bootstrap-server <broker_address> --alter --add-config 'SCRAM-SHA-512=[password=<Password>]' --entity-type users --entity-name <Username>

    例如:

    bin/kafka-configs.sh --bootstrap-server localhost:9092 --alter --add-config 'SCRAM-SHA-512=[password=123456]' --entity-type users --entity-name user1

6.4.8.9. 删除 SASL SCRAM 用户

这个步骤描述了如何在使用 SASL SCRAM 身份验证时删除用户。

先决条件

  • AMQ Streams 安装 在所有将用作 Kafka 代理的主机上。
  • 启用 SASL SCRAM 身份验证。

流程

  • 使用 kafka-configs.sh 工具删除 SASL SCRAM 用户。

    /opt/kafka/bin/kafka-configs.sh --bootstrap-server <broker_address> --alter --delete-config 'SCRAM-SHA-512' --entity-type users --entity-name <Username>

    例如:

    /opt/kafka/bin/kafka-configs.sh --bootstrap-server localhost:9092 --alter --delete-config 'SCRAM-SHA-512' --entity-type users --entity-name user1

6.4.9. 使用基于 OAuth 2.0 令牌的身份验证

AMQ Streams 支持使用 OAUTHBEARERPLAIN 机制使用 OAuth 2.0 身份验证

OAuth 2.0 启用应用程序之间的基于令牌的标准化身份验证和授权,使用中央授权服务器签发对资源有限访问权限的令牌。

您可以配置 OAuth 2.0 身份验证,然后配置 OAuth 2.0 授权

Kafka 代理和客户端都需要配置为使用 OAuth 2.0。OAuth 2.0 身份验证也可以与 简单 或基于 OPA 的 Kafka 授权一起使用。

使用 OAuth 2.0 身份验证时,应用程序客户端可以访问应用服务器上的资源(称为 资源服务器),而无需公开帐户凭据。

应用程序客户端通过访问令牌作为身份验证方法传递,应用服务器也可以用来决定要授予的访问权限级别。授权服务器处理访问权限的授予和关注访问权限的查询。

在 AMQ Streams 上下文中:

  • Kafka 代理充当 OAuth 2.0 资源服务器
  • Kafka 客户端充当 OAuth 2.0 应用程序客户端

Kafka 客户端在 Kafka 代理验证。代理和客户端根据需要与 OAuth 2.0 授权服务器通信,以获取或验证访问令牌。

对于 AMQ Streams 的部署,OAuth 2.0 集成提供:

  • Kafka 代理的服务器端 OAuth 2.0 支持
  • 对 Kafka MirrorMaker、Kafka Connect 和 Kafka Bridge 的客户端 OAuth 2.0 支持

RHEL 上的 AMQ Streams 包括两个 OAuth 2.0 库:

kafka-oauth-client
提供名为 io.strimzi.kafka.oauth.client.JaasClientOauthLoginCallbackHandler 的自定义登录回调处理器类。要处理 OAUTHBEARER 身份验证机制,请使用 Apache Kafka 提供的 OAuthBearerLoginModule 登录回调处理器。
kafka-oauth-common
提供 kafka-oauth-client 库所需的一些功能的帮助程序库。

提供的客户端库还依赖于一些额外的第三方库,例如: keycloak-corejackson-databindslf4j-api

我们建议使用 Maven 项目来打包您的客户端,以确保包含所有依赖项库。依赖项库可能会在以后的版本中有所变化。

其他资源

6.4.9.1. OAuth 2.0 身份验证机制

AMQ Streams 支持 OAUTHBEARER 和 PLAIN 机制进行 OAuth 2.0 身份验证。两个机制都允许 Kafka 客户端与 Kafka 代理建立经过身份验证的会话。客户端、授权服务器和 Kafka 代理之间的身份验证流因每种机制而异。

我们建议您将客户端配置为尽可能使用 OAUTHBEARER。OAUTHBEARER 提供比 PLAIN 更高的安全性,因为客户端凭证不会与 Kafka 代理共享。考虑仅在不支持 OAUTHBEARER 的 Kafka 客户端中使用 PLAIN。

您可以将 Kafka 代理监听程序配置为使用 OAuth 2.0 身份验证来连接客户端。如果需要,您可以在同一 oauth 侦听器上使用 OAUTHBEARER 和 PLAIN 机制。必须支持每个机制的属性必须在 oauth 侦听器配置中明确指定。

OAUTHBEARER 概述

要使用 OAUTHBEARER,请将 Kafka 代理的 OAuth 身份验证监听程序配置中的 sasl.enabled.mechanisms 设置为 OAUTHBEARER。有关详细配置,请参阅 第 6.4.9.2 节 “OAuth 2.0 Kafka 代理配置”

listener.name.client.sasl.enabled.mechanisms=OAUTHBEARER

许多 Kafka 客户端工具使用在协议级别为 OAUTHBEARER 提供基本支持的库。为了支持应用程序开发,AMQ Streams 为上游 Kafka Client Java 库(但不适用于其他库)提供了一个 OAuth 回调处理器。因此,您不需要编写自己的回调处理程序。应用程序客户端可以使用回调处理程序来提供访问令牌。使用 Go 等其他语言编写的客户端必须使用自定义代码连接到授权服务器并获取访问令牌。

使用 OAUTHBEARER 时,客户端使用 Kafka 代理启动会话,用于凭证交换,其中凭证采用回调处理器提供的 bearer 令牌形式。使用回调,您可以使用三种方式配置令牌置备:

  • 客户端 ID 和 Secret (通过使用 OAuth 2.0 客户端凭证 机制)
  • 长期访问令牌,在配置时手动获取
  • 长期刷新令牌,在配置时手动获取
注意

OAUTHBEARER 身份验证只能由支持协议级别的 OAUTHBEARER 机制的 Kafka 客户端使用。

PLAIN 概述

要使用 PLAIN,请将 PLAIN 添加到 sasl.enabled.mechanisms 的值。

listener.name.client.sasl.enabled.mechanisms=OAUTHBEARER,PLAIN

PLAIN 是所有 Kafka 客户端工具使用的简单身份验证机制。要启用 PLAIN 以用于 OAuth 2.0 身份验证,AMQ Streams 提供了 OAuth 2.0 over PLAIN 服务器端的回调。

对于 PLAIN 的 AMQ Streams 实现,客户端凭证不会存储在 ZooKeeper 中。相反,客户端凭证会在兼容授权服务器后进行集中处理,这与使用 OAUTHBEARER 身份验证类似。

当与 OAuth 2.0 over PLAIN 回调一起使用时,Kafka 客户端使用以下方法之一与 Kafka 代理进行身份验证:

  • 客户端 ID 和 secret (通过使用 OAuth 2.0 客户端凭证 机制)
  • 长期访问令牌,在配置时手动获取

对于这两种方法,客户端必须提供 PLAIN usernamepassword 属性,将凭证传递给 Kafka 代理。客户端使用这些属性传递客户端 ID 和机密或用户名和访问令牌。

客户端 ID 和 secret 用于获取访问令牌。

访问令牌作为 password 属性值传递。您可以使用或不使用 $accessToken: 前缀传递访问令牌。

  • 如果您在监听器配置中配置了令牌端点(oauth.token.endpoint.uri),则需要前缀。
  • 如果您没有在监听器配置中配置令牌端点(oauth.token.endpoint.uri),则不需要前缀。Kafka 代理将密码解释为原始访问令牌。

如果将密码设置为访问令牌,则必须将用户名设置为 Kafka 代理从访问令牌获取的相同的主体名称。您可以使用 oauth.username.claim, oauth.fallback.username.claim, oauth.fallback.username.prefix, 和 oauth.userinfo.endpoint.uri 属性在监听器中指定用户名提取选项。用户名提取过程还取决于您的授权服务器;特别是,它将客户端 ID 映射到帐户名称。

注意

PLAIN 上的 OAuth 不支持使用(已弃用)OAuth 2.0 密码授权机制传递用户名和密码(密码授权)。

6.4.9.1.1. 使用属性或变量配置 OAuth 2.0

您可以使用 Java Authentication and Authorization Service(JAAS)属性或环境变量来配置 OAuth 2.0 设置。

  • JAAS 属性在 server.properties 配置文件中配置,并传递为 listener.name.LISTENER-NAME.oauthbearer.sasl.jaas.config 属性的键值对。
  • 如果使用环境变量,您仍然需要在 server.properties 文件中提供 listener.name.LISTENER-NAME.oauthbearer.sasl.jaas.config 属性,但您可以忽略其他 JAAS 属性。

    您可以使用大写或大写环境变量命名约定。

AMQ Streams OAuth 2.0 库使用以以下开头的属性:

6.4.9.2. OAuth 2.0 Kafka 代理配置

OAuth 2.0 身份验证的 Kafka 代理配置涉及:

  • 在授权服务器中创建 OAuth 2.0 客户端
  • 在 Kafka 集群中配置 OAuth 2.0 身份验证
注意

与授权服务器相关,Kafka 代理和 Kafka 客户端都被视为 OAuth 2.0 客户端。

6.4.9.2.1. 授权服务器上的 OAuth 2.0 客户端配置

要配置 Kafka 代理以验证会话启动期间收到的令牌,建议的做法是在授权服务器中创建一个 OAuth 2.0 client 定义(配置为 confidential),并启用了以下客户端凭证:

  • 客户端 ID kafka-broker (例如)
  • 客户端 ID 和 secret 作为身份验证机制
注意

在使用授权服务器的非公共内省端点时,您只需要使用客户端 ID 和 secret。使用公共授权服务器端点时通常不需要凭据,就像快速本地 JWT 令牌验证一样。

6.4.9.2.2. Kafka 集群中的 OAuth 2.0 身份验证配置

要在 Kafka 集群中使用 OAuth 2.0 身份验证,您可以在 Kafka server.properties 文件中为 Kafka 集群启用 OAuth 身份验证监听程序配置。需要最低配置。您还可以配置 TLS 侦听器,其中 TLS 用于内部代理通信。

您可以使用以下方法之一为授权服务器配置令牌验证代理:

  • 快速本地令牌验证: JWKS 端点与签名的 JWT 格式的访问令牌相结合
  • 内省端点

您可以配置 OAUTHBEARER 或 PLAIN 身份验证,或两者。

以下示例显示了应用 全局 监听器配置的最低配置,这意味着,内部代理间通信通过与应用程序客户端相同的监听程序进行。

这个示例还显示了一个特定监听程序的 OAuth 2.0 配置,在其中您可以指定 listener.name.LISTENER-NAME.sasl.enabled.mechanisms 而不是 sasl.enabled.mechanismsLISTENER-NAME 是监听器不区分大小写的名称。在这里,我们将侦听器的 CLIENT 命名为 listener.name.client.sasl.enabled.mechanisms

这个示例使用 OAUTHBEARER 身份验证。

示例:使用 JWKS 端点进行 OAuth 2.0 身份验证的最小监听程序配置

sasl.enabled.mechanisms=OAUTHBEARER 1
listeners=CLIENT://0.0.0.0:9092 2
listener.security.protocol.map=CLIENT:SASL_PLAINTEXT 3
listener.name.client.sasl.enabled.mechanisms=OAUTHBEARER 4
sasl.mechanism.inter.broker.protocol=OAUTHBEARER 5
inter.broker.listener.name=CLIENT 6
listener.name.client.oauthbearer.sasl.server.callback.handler.class=io.strimzi.kafka.oauth.server.JaasServerOauthValidatorCallbackHandler 7
listener.name.client.oauthbearer.sasl.jaas.config=org.apache.kafka.common.security.oauthbearer.OAuthBearerLoginModule required \ 8
  oauth.valid.issuer.uri="https://<oauth_server_address>" \ 9
  oauth.jwks.endpoint.uri="https://<oauth_server_address>/jwks" \ 10
  oauth.username.claim="preferred_username"  \ 11
  oauth.client.id="kafka-broker" \ 12
  oauth.client.secret="kafka-secret" \ 13
  oauth.token.endpoint.uri="https://<oauth_server_address>/token" ; 14
listener.name.client.oauthbearer.sasl.login.callback.handler.class=io.strimzi.kafka.oauth.client.JaasClientOauthLoginCallbackHandler 15
listener.name.client.oauthbearer.connections.max.reauth.ms=3600000 16

1
为通过 SASL 的凭据交换启用 OAUTHBEARER 机制。
2
为客户端应用程序配置要连接的监听程序。系统主机名 用作公告的主机名,客户端必须解析才能重新连接。本例中,侦听器名为 CLIENT
3
指定监听器的频道协议。SASL_SSL 用于 TLS。SASL_PLAINTEXT 用于未加密的连接(无 TLS),但存在丢失和截获 TCP 连接层的风险。
4
指定 CLIENT 侦听器的 OAUTHBEARER 机制。客户端名称(CLIENT)通常在 listeners 属性中使用大写指定,对于 listener.name 属性是小写 (listener.name.client),当为 listener.name.client.* 属性的一部分时是小写。
5
指定用于代理间通信的 OAUTHBEARER 机制。
6
指定代理间通信的监听程序。配置需要规格才能有效。
7
在客户端监听器上配置 OAuth 2.0 身份验证。
8
配置客户端和代理间通信的身份验证设置。oauth.client.idoauth.client.secretauth.token.endpoint.uri 属性与 inter-broker 配置相关。
9
有效的签发者 URI。只有此签发者发布的访问令牌才会被接受。例如 :https://AUTH-SERVER-ADDRESS/auth/realms/REALM-NAME
10
JWKS 端点 URL。例如: https://AUTH-SERVER-ADDRESS/auth/realms/REALM-NAME/protocol/openid-connect/certs
11
令牌声明(或密钥)包含令牌中实际用户名。用户名是用于识别用户的 主体。该值将取决于身份验证流和使用的授权服务器。如果需要,您可以使用 JsonPath 表达式,如 "['user.info'].['user.id']",从令牌中的嵌套 JSON 属性检索用户名。
12
Kafka 代理的客户端 ID,适用于所有代理。这是在 授权服务器中注册的客户端作为 kafka-broker
13
Kafka 代理的 secret,适用于所有代理。
14
您的授权服务器的 OAuth 2.0 令牌端点 URL。对于生产环境,始终使用 https:// urls。例如: https://AUTH-SERVER-ADDRESS/auth/realms/REALM-NAME/protocol/openid-connect/token
15
为代理间通信启用(且只需要)OAuth 2.0 身份验证。
16
(可选)在令牌过期时强制会话过期,并激活 Kafka 重新身份验证机制。如果指定的值小于访问令牌过期的时间,那么客户端必须在实际令牌到期前重新验证。默认情况下,当访问令牌过期时,会话不会过期,客户端也不会尝试重新身份验证。

以下示例显示了 TLS 侦听器的最低配置,其中 TLS 用于内部代理通信。

示例:用于 OAuth 2.0 身份验证的 TLS 侦听器配置

listeners=REPLICATION://kafka:9091,CLIENT://kafka:9092 1
listener.security.protocol.map=REPLICATION:SSL,CLIENT:SASL_PLAINTEXT 2
listener.name.client.sasl.enabled.mechanisms=OAUTHBEARER
inter.broker.listener.name=REPLICATION
listener.name.replication.ssl.keystore.password=<keystore_password> 3
listener.name.replication.ssl.truststore.password=<truststore_password>
listener.name.replication.ssl.keystore.type=JKS
listener.name.replication.ssl.truststore.type=JKS
listener.name.replication.ssl.secure.random.implementation=SHA1PRNG 4
listener.name.replication.ssl.endpoint.identification.algorithm=HTTPS 5
listener.name.replication.ssl.keystore.location=<path_to_keystore> 6
listener.name.replication.ssl.truststore.location=<path_to_truststore> 7
listener.name.replication.ssl.client.auth=required 8
listener.name.client.oauthbearer.sasl.server.callback.handler.class=io.strimzi.kafka.oauth.server.JaasServerOauthValidatorCallbackHandler
listener.name.client.oauthbearer.sasl.jaas.config=org.apache.kafka.common.security.oauthbearer.OAuthBearerLoginModule required \ 9
  oauth.valid.issuer.uri="https://<oauth_server_address>" \
  oauth.jwks.endpoint.uri="https://<oauth_server_address>/jwks" \
  oauth.username.claim="preferred_username" ;

1
在代理间通信和客户端应用程序需要单独的配置。
2
REPLICATION 侦听器配置为使用 TLS,而 CLIENT 侦听器则通过未加密的频道使用 SASL。客户端可以在生产环境中使用加密的频道(SASL_SSL)。
3
ssl. 属性定义 TLS 配置。
4
随机数生成器实施。如果没有设置,则使用 Java 平台 SDK 默认。
5
主机名验证。如果设置为空字符串,则主机名验证将关闭。如果没有设置,则默认值为 HTTPS,它会强制对服务器证书进行主机名验证。
6
侦听器的密钥存储路径。
7
监听器的信任存储的路径。
8
指定 REPLICATION 侦听器的客户端必须在建立 TLS 连接时与客户端证书进行身份验证(用于内部代理连接)。
9
为 OAuth 2.0 配置 CLIENT 侦听器。与授权服务器的连接应使用安全 HTTPS 连接。

以下示例显示了使用 PLAIN 验证机制通过 SASL 进行凭证交换的 OAuth 2.0 身份验证的最低配置。使用快速本地令牌验证。

示例: PLAIN 身份验证的最低监听程序配置

listeners=CLIENT://0.0.0.0:9092 1
listener.security.protocol.map=CLIENT:SASL_PLAINTEXT 2
listener.name.client.sasl.enabled.mechanisms=OAUTHBEARER,PLAIN 3
sasl.mechanism.inter.broker.protocol=OAUTHBEARER 4
inter.broker.listener.name=CLIENT 5
listener.name.client.oauthbearer.sasl.server.callback.handler.class=io.strimzi.kafka.oauth.server.JaasServerOauthValidatorCallbackHandler 6
listener.name.client.oauthbearer.sasl.jaas.config=org.apache.kafka.common.security.oauthbearer.OAuthBearerLoginModule required \ 7
  oauth.valid.issuer.uri="http://<auth_server>/auth/realms/<realm>" \ 8
  oauth.jwks.endpoint.uri="https://<auth_server>/auth/realms/<realm>/protocol/openid-connect/certs" \ 9
  oauth.username.claim="preferred_username"  \ 10
  oauth.client.id="kafka-broker" \ 11
  oauth.client.secret="kafka-secret" \ 12
  oauth.token.endpoint.uri="https://<oauth_server_address>/token" ; 13
listener.name.client.oauthbearer.sasl.login.callback.handler.class=io.strimzi.kafka.oauth.client.JaasClientOauthLoginCallbackHandler 14
listener.name.client.plain.sasl.server.callback.handler.class=io.strimzi.kafka.oauth.server.plain.JaasServerOauthOverPlainValidatorCallbackHandler 15
listener.name.client.plain.sasl.jaas.config=org.apache.kafka.common.security.plain.PlainLoginModule required \ 16
  oauth.valid.issuer.uri="https://<oauth_server_address>" \ 17
  oauth.jwks.endpoint.uri="https://<oauth_server_address>/jwks" \ 18
  oauth.username.claim="preferred_username"  \ 19
  oauth.token.endpoint.uri="http://<auth_server>/auth/realms/<realm>/protocol/openid-connect/token" ; 20
connections.max.reauth.ms=3600000 21

1
配置监听器(本例中为 CLIENT ),供客户端应用程序连接。系统主机名 用作公告的主机名,客户端必须解析才能重新连接。由于这是唯一配置的监听程序,因此它也用于代理间通信。
2
将示例 CLIENT 侦听器配置为通过未加密的频道使用 SASL。在生产环境中,客户端应使用加密的频道(SASL_SSL)来保护在 TCP 连接层上弹出和截获。
3
为通过 SASL 和 OAUTHBEARER 进行凭证交换启用 PLAIN 身份验证机制。OAUTHBEARER 也被指定,因为代理间通信需要它。Kafka 客户端可以选择使用哪个机制进行连接。
4
指定用于代理间通信的 OAUTHBEARER 身份验证机制。
5
为内部代理通信指定监听器(本例中为 CLIENT)。配置有效需要此项。
6
为 OAUTHBEARER 机制配置服务器回调处理器。
7
使用 OAUTHBEARER 机制配置客户端和代理间通信的身份验证设置。oauth.client.idoauth.client.secretoauth.token.endpoint.uri 属性与 inter-broker 配置相关。
8
有效的签发者 URI。只接受来自此签发者的访问令牌。例如: https://AUTH-SERVER-ADDRESS/auth/realms/REALM-NAME
9
JWKS 端点 URL。例如 :https://AUTH-SERVER-ADDRESS/auth/realms/REALM-NAME/protocol/openid-connect/certs
10
令牌声明(或密钥)包含令牌中实际用户名。用户名是用于识别用户的 主体。该值将取决于身份验证流和使用的授权服务器。如果需要,您可以使用 JsonPath 表达式,如 "['user.info'].['user.id']",从令牌中的嵌套 JSON 属性检索用户名。
11
Kafka 代理的客户端 ID,适用于所有代理。这是在 授权服务器中注册的客户端作为 kafka-broker
12
Kafka 代理的 secret (所有代理都相同)。
13
您的授权服务器的 OAuth 2.0 令牌端点 URL。对于生产环境,始终使用 https:// urls。例如 :https://AUTH-SERVER-ADDRESS/auth/realms/REALM-NAME/protocol/openid-connect/token
14
为内部代理通信启用 OAuth 2.0 身份验证。
15
PLAIN 身份验证配置服务器回调处理器。
16
使用 PLAIN 身份验证为客户端通信配置身份验证设置。

oauth.token.endpoint.uri 是一个可选属性,它使用 OAuth 2.0 客户端凭证机制启用 OAuth 2.0 over PLAIN。

17
有效的签发者 URI。只接受来自此签发者的访问令牌。例如: https://AUTH-SERVER-ADDRESS/auth/realms/REALM-NAME
18
JWKS 端点 URL。例如 :https://AUTH-SERVER-ADDRESS/auth/realms/REALM-NAME/protocol/openid-connect/certs
19
令牌声明(或密钥)包含令牌中实际用户名。用户名是用于识别用户的 主体。该值将取决于身份验证流和使用的授权服务器。如果需要,您可以使用 JsonPath 表达式,如 "['user.info'].['user.id']",从令牌中的嵌套 JSON 属性检索用户名。
20
您的授权服务器的 OAuth 2.0 令牌端点 URL。PLAIN 机制的额外配置。如果指定,客户端可以使用 $accessToken: 前缀将访问令牌 作为密码 来通过 PLAIN 进行身份验证。

对于生产环境,始终使用 https:// urls。例如: https://AUTH-SERVER-ADDRESS/auth/realms/REALM-NAME/protocol/openid-connect/token

21
(可选)在令牌过期时强制会话过期,并激活 Kafka 重新身份验证机制。如果指定的值小于访问令牌过期的时间,那么客户端必须在实际令牌到期前重新验证。默认情况下,当访问令牌过期时,会话不会过期,客户端也不会尝试重新身份验证。
6.4.9.2.3. 快速本地 JWT 令牌验证配置

快速本地 JWT 令牌验证在本地检查 JWT 令牌签名。

本地检查可确保令牌:

  • 通过包含访问令牌的 Bearer 的(typ)声明值来达到类型
  • 有效(未过期)
  • 具有与 validIssuerURI 匹配的签发者

在配置监听程序时,您可以指定 有效的签发者 URI,以便授权服务器未签发的任何令牌都会被拒绝。

授权服务器不需要在快速本地 JWT 令牌验证期间联系。您可以通过指定 OAuth 2.0 授权服务器公开的 JWKs 端点 URI 来激活快速本地 JWT 令牌验证。端点包含验证已签名的 JWT 令牌的公钥,这些令牌由 Kafka 客户端作为凭证发送。

注意

所有与授权服务器的通信都应该使用 HTTPS 执行。

对于 TLS 侦听器,您可以配置证书信任存储并指向信任存储文件。

快速本地 JWT 令牌验证的属性示例

listener.name.client.oauthbearer.sasl.jaas.config=org.apache.kafka.common.security.oauthbearer.OAuthBearerLoginModule required \
  oauth.valid.issuer.uri="https://<oauth_server_address>" \ 1
  oauth.jwks.endpoint.uri="https://<oauth_server_address>/jwks" \ 2
  oauth.jwks.refresh.seconds="300" \ 3
  oauth.jwks.refresh.min.pause.seconds="1" \ 4
  oauth.jwks.expiry.seconds="360" \ 5
  oauth.username.claim="preferred_username" \ 6
  oauth.ssl.truststore.location="<path_to_truststore_p12_file>" \ 7
  oauth.ssl.truststore.password="<truststore_password>" \ 8
  oauth.ssl.truststore.type="PKCS12" ; 9

1
有效的签发者 URI。只有此签发者发布的访问令牌才会被接受。例如 :https://AUTH-SERVER-ADDRESS/auth/realms/REALM-NAME
2
JWKS 端点 URL。例如: https://AUTH-SERVER-ADDRESS/auth/realms/REALM-NAME/protocol/openid-connect/certs
3
端点刷新之间的周期(默认 300)。
4
连续尝试刷新 JWKS 公钥之间的最小暂停(以秒为单位)。当遇到未知签名密钥时,JWKS 密钥刷新在常规定期调度后调度,且至少在最后一次刷新尝试后出现指定暂停。刷新密钥遵循 exponential backoff 规则,重试不成功刷新,且持续增加暂停,直到它到达 oauth.jwks.refresh.seconds。默认值为 1。
5
JWKs 证书在过期前被视为有效的持续时间。默认为 360 秒。如果您指定较长的时间,请考虑允许访问撤销的证书的风险。
6
令牌声明(或密钥)包含令牌中实际用户名。用户名是用于识别用户的 主体。该值将取决于身份验证流和使用的授权服务器。如果需要,您可以使用 JsonPath 表达式,如 "['user.info'].['user.id']",从令牌中的嵌套 JSON 属性检索用户名。
7
TLS 配置中使用的信任存储的位置。
8
访问信任存储的密码。
9
PKCS #12 格式的 truststore 类型。
6.4.9.2.4. OAuth 2.0 内省端点配置

使用 OAuth 2.0 内省端点验证令牌会将收到的访问令牌视为不透明。Kafka 代理向内省端点发送访问令牌,该端点使用验证所需的令牌信息进行响应。最重要的是,如果特定的访问令牌有效,它会返回最新的信息,以及令牌何时到期的信息。

要配置基于 OAuth 2.0 内省的验证,您可以指定一个 内省端点 URI,而不是为快速本地 JWT 令牌验证指定的 JWKs 端点 URI。根据授权服务器,通常必须指定 client IDclient secret,因为内省端点通常受到保护。

内省端点的属性示例

listener.name.client.oauthbearer.sasl.jaas.config=org.apache.kafka.common.security.oauthbearer.OAuthBearerLoginModule required \
  oauth.introspection.endpoint.uri="https://<oauth_server_address>/introspection" \ 1
  oauth.client.id="kafka-broker" \ 2
  oauth.client.secret="kafka-broker-secret" \ 3
  oauth.ssl.truststore.location="<path_to_truststore_p12_file>" \ 4
  oauth.ssl.truststore.password="<truststore_password>" \ 5
  oauth.ssl.truststore.type="PKCS12" \ 6
  oauth.username.claim="preferred_username" ; 7

1
OAuth 2.0 内省端点 URI。例如: https://AUTH-SERVER-ADDRESS/auth/realms/REALM-NAME/protocol/openid-connect/token/introspect
2
Kafka 代理的客户端 ID。
3
Kafka 代理的 secret。
4
TLS 配置中使用的信任存储的位置。
5
访问信任存储的密码。
6
PKCS #12 格式的 truststore 类型。
7
令牌声明(或密钥)包含令牌中实际用户名。用户名是用于识别用户的 主体。该值将取决于身份验证流和使用的授权服务器。如果需要,您可以使用 JsonPath 表达式,如 "['user.info'].['user.id']",从令牌中的嵌套 JSON 属性检索用户名。

6.4.9.3. Kafka 代理的会话重新身份验证

您可以将 OAuth 侦听器配置为使用 Kafka 会话重新身份验证 Kafka 客户端和 Kafka 代理之间的 OAuth 2.0 会话。这种机制在定义的时间段内强制实施客户端和代理之间经过身份验证的会话的到期。当会话过期时,客户端会立即使用现有连接而不是丢弃它来启动新的会话。

会话重新身份验证默认被禁用。您可以在 server.properties 文件中启用它。为启用了 OAUTHBEARER 或 PLAIN 作为 SASL 机制的 TLS 侦听器设置 connections.max.reauth.ms 属性。

您可以指定每个监听器的会话重新身份验证。例如:

listener.name.client.oauthbearer.connections.max.reauth.ms=3600000

会话重新身份验证必须由客户端使用的 Kafka 客户端库支持。

会话重新身份验证可用于快速 本地 JWT内省端点 令牌验证。

客户端重新身份验证

当代理的经过身份验证的会话过期时,客户端必须通过向代理发送新的有效的访问令牌来重新验证现有的会话。

如果令牌验证成功,则使用现有连接启动新的客户端会话。如果客户端无法重新验证,代理会在进一步尝试发送或接收消息时关闭连接。如果在代理上启用了重新身份验证机制,使用 Kafka 客户端库 2.2 或更高版本的 Java 客户端会自动重新验证。

如果使用,会话重新身份验证也适用于刷新令牌。当会话过期时,客户端会使用其刷新令牌来刷新访问令牌。然后,客户端使用新的访问令牌通过现有的连接重新进行身份验证。

OAUTHBEARER 和 PLAIN 的会话过期

配置会话重新身份验证后,对于 OAUTHBEARER 和 PLAIN 身份验证,会话到期会有所不同。

对于 OAUTHBEARER 和 PLAIN,使用 客户端 ID 和 secret 方法:

  • 代理的经过身份验证的会话将在配置的 connections.max.reauth.ms 中过期。
  • 如果访问令牌在配置时间之前过期,则会话将过期。

对于使用 长期访问令牌 方法的 PLAIN:

  • 代理的经过身份验证的会话将在配置的 connections.max.reauth.ms 中过期。
  • 如果访问令牌在配置时间之前过期,则重新身份验证将失败。虽然尝试会话重新身份验证,但 PLAIN 没有刷新令牌的机制。

如果没有配置 connection.max.reauth.ms,OAUTHBEARER 和 PLAIN 客户端可以无限期地连接到代理,而无需重新验证。经过身份验证的会话不会以访问令牌到期结尾。但是,这可以在配置授权时考虑,例如使用 keycloak 授权或安装自定义授权器。

6.4.9.4. OAuth 2.0 Kafka 客户端配置

Kafka 客户端配置有:

  • 从授权服务器获取有效访问令牌(客户端 ID 和 Secret)所需的凭证
  • 使用授权服务器提供的工具获取有效的长期访问令牌或刷新令牌

发送到 Kafka 代理的唯一信息是一个访问令牌。用于与授权服务器进行身份验证的凭证从不会发送到代理。

当客户端获取访问令牌时,不需要进一步与授权服务器通信。

最简单的机制是使用客户端 ID 和 Secret 进行身份验证。使用长期的访问令牌或长期的刷新令牌会增加复杂性,因为对授权服务器工具还有额外的依赖。

注意

如果您使用长期访问令牌,您可能需要在授权服务器中配置客户端,以增加令牌的最大生命周期。

如果 Kafka 客户端没有直接配置访问令牌,客户端会在 Kafka 会话发起授权服务器的过程中交换访问令牌的凭证。Kafka 客户端交换:

  • 客户端 ID 和 Secret
  • 客户端 ID、刷新令牌和(可选)secret
  • 用户名和密码,带有客户端 ID 和(可选)secret

6.4.9.5. OAuth 2.0 客户端身份验证流程

OAuth 2.0 身份验证流程取决于底层 Kafka 客户端和 Kafka 代理配置。该流还必须被使用的授权服务器支持。

Kafka 代理侦听器配置决定了客户端如何使用访问令牌进行身份验证。客户端可以传递客户端 ID 和机密来请求访问令牌。

如果侦听器配置为使用 PLAIN 身份验证,客户端可以通过客户端 ID 和 secret 或用户名和访问令牌进行身份验证。这些值作为 PLAIN 机制 usernamepassword 属性传递。

侦听器配置支持以下令牌验证选项:

  • 您可以使用基于 JWT 签名检查和本地令牌内省的快速本地令牌验证,而无需联系授权服务器。授权服务器提供带有公共证书的 JWKS 端点,用于验证令牌中的签名。
  • 您可以使用对授权服务器提供的令牌内省端点的调用。每次建立新的 Kafka 代理连接时,代理都会将从客户端收到的访问令牌传递给授权服务器。Kafka 代理检查响应以确认令牌是否有效。
注意

授权服务器可能只允许使用不透明访问令牌,这意味着无法进行本地令牌验证。

Kafka 客户端凭证也可以为以下类型的身份验证配置:

  • 使用之前生成的长期访问令牌直接进行本地访问
  • 与授权服务器联系以获取要发布的新访问令牌(使用客户端 ID 和 secret、刷新令牌或用户名和密码)
6.4.9.5.1. 使用 SASL OAUTHBEARER 机制的客户端身份验证流示例

您可以使用 SASL OAUTHBEARER 机制将以下通信流用于 Kafka 身份验证。

使用客户端 ID 和 secret 的客户端,并将代理委派给授权服务器

Client using client ID and secret with broker delegating validation to authorization server

  1. Kafka 客户端使用客户端 ID 和 secret 从授权服务器请求访问令牌,以及可选的刷新令牌。或者,客户端也可以使用用户名和密码进行身份验证。
  2. 授权服务器生成新的访问令牌。
  3. Kafka 客户端使用 SASL OAUTHBEARER 机制通过访问令牌通过 Kafka 代理进行身份验证。
  4. Kafka 代理通过使用自己的客户端 ID 和 secret,在授权服务器上调用令牌内省端点来验证访问令牌。
  5. 如果令牌有效,则会建立 Kafka 客户端会话。

使用客户端 ID 和 secret 的客户端以及执行快速本地令牌验证的代理

Client using client ID and secret with broker performing fast local token validation

  1. Kafka 客户端使用令牌端点、使用客户端 ID 和 secret 以及刷新令牌(可选)从令牌端点验证。或者,客户端也可以使用用户名和密码进行身份验证。
  2. 授权服务器生成新的访问令牌。
  3. Kafka 客户端使用 SASL OAUTHBEARER 机制通过访问令牌通过 Kafka 代理进行身份验证。
  4. Kafka 代理使用 JWT 令牌签名检查和本地令牌内省在本地验证访问令牌。

使用长期访问令牌的客户端,并将代理委派给授权服务器

Client using long-lived access token with broker delegating validation to authorization server

  1. Kafka 客户端使用 SASL OAUTHBEARER 机制通过 Kafka 代理进行身份验证,以传递长期访问令牌。
  2. Kafka 代理通过使用自己的客户端 ID 和 secret,在授权服务器上调用令牌内省端点来验证访问令牌。
  3. 如果令牌有效,则会建立 Kafka 客户端会话。

使用长期访问令牌的客户端,以及执行快速本地验证的代理

Client using long-lived access token with broker performing fast local validation

  1. Kafka 客户端使用 SASL OAUTHBEARER 机制通过 Kafka 代理进行身份验证,以传递长期访问令牌。
  2. Kafka 代理使用 JWT 令牌签名检查和本地令牌内省在本地验证访问令牌。
警告

快速的本地 JWT 令牌签名验证仅适用于短期的令牌,因为如果已撤销令牌,就不会通过授权服务器检查该授权服务器。令牌到期时间写入到令牌,但可以随时进行撤销,因此不能在不联系授权服务器的情况下被考虑。任何发布的令牌都将被视为有效,直到其过期为止。

6.4.9.5.2. 使用 SASL PLAIN 机制的客户端身份验证流示例

您可以使用 OAuth PLAIN 机制将以下通信流用于 Kafka 身份验证。

使用客户端 ID 和 secret 的客户端以及代理获取客户端的访问令牌

Client using a client ID and secret with the broker obtaining the access token for the client

  1. Kafka 客户端或传递一个 clientId 作为用户名,以及一个 secret 作为密码。
  2. Kafka 代理使用令牌端点将 clientIdsecret 传递给授权服务器。
  3. 如果客户端凭据无效,授权服务器会返回一个新的访问令牌或错误。
  4. Kafka 代理使用以下方法之一验证令牌:

    1. 如果指定了令牌内省端点,Kafka 代理通过在授权服务器上调用端点来验证访问令牌。如果令牌验证成功,则会建立会话。
    2. 如果使用本地令牌内省,则不会向授权服务器发出请求。Kafka 代理使用 JWT 令牌签名检查在本地验证访问令牌。

使用长期访问令牌(无需客户端 ID 和 secret)的客户端

Client using a long-lived access token without a client ID and secret

  1. Kafka 客户端会传递用户名和密码。密码提供在运行客户端前手动和配置的访问令牌的值。
  2. 密码通过或不使用 $accessToken: 字符串前缀来传递,具体取决于 Kafka 代理侦听程序是否配置了令牌端点来进行身份验证。

    1. 如果配置了令牌端点,密码应该以 $accessToken: 前缀,以便代理知道 password 参数包含访问令牌,而不是客户端 secret。Kafka 代理将用户名解释为帐户用户名。
    2. 如果没有在 Kafka 代理监听器上配置令牌端点(强制使用 no-client-credentials 模式),密码应提供没有前缀的访问令牌。Kafka 代理将用户名解释为帐户用户名。在此模式中,客户端不使用客户端 ID 和 secret,password 参数始终解释为原始访问令牌。
  3. Kafka 代理使用以下方法之一验证令牌:

    1. 如果指定了令牌内省端点,Kafka 代理通过在授权服务器上调用端点来验证访问令牌。如果令牌验证成功,则会建立会话。
    2. 如果使用本地令牌内省,则不会向授权服务器发出请求。Kafka 代理使用 JWT 令牌签名检查在本地验证访问令牌。

6.4.9.6. 配置 OAuth 2.0 身份验证

OAuth 2.0 用于在 Kafka 客户端和 AMQ Streams 组件间交互。

要将 OAuth 2.0 用于 AMQ Streams,您必须:

6.4.9.6.1. 将 Red Hat Single Sign-On 配置为 OAuth 2.0 授权服务器

这个步骤描述了如何将 Red Hat Single Sign-On 部署为授权服务器,并将其配置为与 AMQ Streams 集成。

授权服务器为身份验证和授权提供了一个中央点,以及用户、客户端和权限的管理。Red Hat Single Sign-On 具有一个域的概念, 代表一组单独的用户、客户端、权限和其他配置。您可以使用默认 master 域,或创建新域。每个 realm 会公开自己的 OAuth 2.0 端点,这意味着应用程序客户端和应用服务器都需要使用相同的域。

要将 OAuth 2.0 与 AMQ Streams 搭配使用,请使用部署 Red Hat Single Sign-On 来创建和管理身份验证域。

注意

如果您已经部署了 Red Hat Single Sign-On,您可以跳过部署步骤并使用您当前的部署。

开始前

您需要熟悉使用红帽单点登录。

有关安装和管理说明,请参阅:

先决条件

  • AMQ Streams 和 Kafka 正在运行

对于 Red Hat Single Sign-On 部署:

流程

  1. 安装 Red Hat Single Sign-On。

    您可以从 ZIP 文件或使用 RPM 安装。

  2. 登录到 Red Hat Single Sign-On Admin 控制台,为 AMQ Streams 创建 OAuth 2.0 策略。

    部署 Red Hat Single Sign-On 时会提供登录详情。

  3. 创建并启用域。

    您可以使用现有的 master 域。

  4. 如果需要,调整域的会话和令牌超时。
  5. 创建名为 kafka-broker 的客户端。
  6. Settings 选项卡中设置:

    • Access Type to Confidential
    • Standard Flow EnabledOFF 为这个客户端禁用 Web 登录
    • Service Accounts EnabledON,以允许此客户端在其自己的名称中进行身份验证
  7. 在继续操作前,点 Save
  8. Credentials 选项卡中,记录使用 AMQ Streams Kafka 集群配置的 secret。
  9. 对要连接到 Kafka 代理的任何应用程序客户端重复客户端创建步骤。

    为每个新客户端创建一个定义。

    在配置中,您将使用名称作为客户端 ID。

接下来要做什么

部署和配置授权服务器后,将 Kafka 代理配置为使用 OAuth 2.0

6.4.9.6.2. 为 Kafka 代理配置 OAuth 2.0 支持

此流程描述了如何配置 Kafka 代理,以便代理监听程序可以使用授权服务器使用 OAuth 2.0 身份验证。

我们建议通过配置 TLS 侦听程序在加密接口上使用 OAuth 2.0。不建议使用普通监听程序。

使用支持您选择的授权服务器的属性以及您要实现的授权类型来配置 Kafka 代理。

开始前

有关 Kafka 代理监听程序的配置和验证的更多信息,请参阅:

有关监听程序配置中使用的属性的描述,请参阅:

先决条件

  • AMQ Streams 和 Kafka 正在运行
  • 部署 OAuth 2.0 授权服务器

流程

  1. server.properties 文件中配置 Kafka 代理监听程序配置。

    例如,使用 OAUTHBEARER 机制:

    sasl.enabled.mechanisms=OAUTHBEARER
    listeners=CLIENT://0.0.0.0:9092
    listener.security.protocol.map=CLIENT:SASL_PLAINTEXT
    listener.name.client.sasl.enabled.mechanisms=OAUTHBEARER
    sasl.mechanism.inter.broker.protocol=OAUTHBEARER
    inter.broker.listener.name=CLIENT
    listener.name.client.oauthbearer.sasl.server.callback.handler.class=io.strimzi.kafka.oauth.server.JaasServerOauthValidatorCallbackHandler
    listener.name.client.oauthbearer.sasl.jaas.config=org.apache.kafka.common.security.oauthbearer.OAuthBearerLoginModule required ;
    listener.name.client.oauthbearer.sasl.login.callback.handler.class=io.strimzi.kafka.oauth.client.JaasClientOauthLoginCallbackHandler
  2. 将代理连接设置配置为 listener.name.client.oauthbearer.sasl.jaas.config 的一部分。

    此处的示例显示了连接配置选项。

    示例 1:使用 JWKS 端点配置进行本地令牌验证

    listener.name.client.oauthbearer.sasl.jaas.config=org.apache.kafka.common.security.oauthbearer.OAuthBearerLoginModule required \
      oauth.valid.issuer.uri="https://<oauth_server_address>/auth/realms/<realm_name>" \
      oauth.jwks.endpoint.uri="https://<oauth_server_address>/auth/realms/<realm_name>/protocol/openid-connect/certs" \
      oauth.jwks.refresh.seconds="300" \
      oauth.jwks.refresh.min.pause.seconds="1" \
      oauth.jwks.expiry.seconds="360" \
      oauth.username.claim="preferred_username" \
      oauth.ssl.truststore.location="<path_to_truststore_p12_file>" \
      oauth.ssl.truststore.password="<truststore_password>" \
      oauth.ssl.truststore.type="PKCS12" ;
    listener.name.client.oauthbearer.connections.max.reauth.ms=3600000

    示例 2:通过 OAuth 2.0 内省端点将令牌验证委派给授权服务器

    listener.name.client.oauthbearer.sasl.jaas.config=org.apache.kafka.common.security.oauthbearer.OAuthBearerLoginModule required \
      oauth.introspection.endpoint.uri="https://<oauth_server_address>/auth/realms/<realm_name>/protocol/openid-connect/introspection" \
      # ...

  3. 如果需要,配置对授权服务器的访问。

    生产环境通常需要这一步,除非使用 service mesh 等技术来配置容器外的安全频道。

    1. 提供用于连接到安全授权服务器的自定义信任存储。访问授权服务器时始终需要 SSL。

      设置属性来配置信任存储。

      例如:

      listener.name.client.oauthbearer.sasl.jaas.config=org.apache.kafka.common.security.oauthbearer.OAuthBearerLoginModule required \
        # ...
        oauth.client.id="kafka-broker" \
        oauth.client.secret="kafka-broker-secret" \
        oauth.ssl.truststore.location="<path_to_truststore_p12_file>" \
        oauth.ssl.truststore.password="<truststore_password>" \
        oauth.ssl.truststore.type="PKCS12" ;
    2. 如果证书主机名与访问 URL 主机名不匹配,您可以关闭证书颁发机构验证:

      oauth.ssl.endpoint.identification.algorithm=""

      检查可确保与授权服务器的连接是真实的。您可能希望在非生产环境中关闭验证。

  4. 根据您选择的身份验证流程配置附加属性:

    listener.name.client.oauthbearer.sasl.jaas.config=org.apache.kafka.common.security.oauthbearer.OAuthBearerLoginModule required \
      # ...
      oauth.token.endpoint.uri="https://<oauth_server_address>/auth/realms/<realm_name>/protocol/openid-connect/token" \ 1
      oauth.custom.claim.check="@.custom == 'custom-value'" \ 2
      oauth.scope="<scope>" \ 3
      oauth.check.audience="true" \ 4
      oauth.audience="<audience>" \ 5
      oauth.valid.issuer.uri="https://https://<oauth_server_address>/auth/<realm_name>" \ 6
      oauth.client.id="kafka-broker" \ 7
      oauth.client.secret="kafka-broker-secret" \ 8
      oauth.connect.timeout.seconds=60 \ 9
      oauth.read.timeout.seconds=60 \ 10
      oauth.http.retries=2 \ 11
      oauth.http.retry.pause.millis=300 \ 12
      oauth.groups.claim="$.groups" \ 13
      oauth.groups.claim.delimiter="," ; 14
    1
    您的授权服务器的 OAuth 2.0 令牌端点 URL。对于生产环境,始终使用 https:// urls。当使用 KeycloakAuthorizer 或启用了 OAuth 2.0 的监听程序时,需要用于代理间通信。
    2
    (可选 )自定义声明检查。JsonPath 过滤器查询,在验证过程中将额外的自定义规则应用到 JWT 访问令牌。如果访问令牌不包含必要的数据,则会被拒绝。使用 introspection 端点方法时,自定义检查将应用到内省端点响应 JSON。
    3
    (可选)传递给令牌端点的 scope 参数。获取访问令牌进行代理身份验证时使用的 scope。它还在使用 clientIdsecret 的 PLAIN 客户端验证中用于 OAuth 2.0 的客户端名称。这只会影响获取令牌的能力,以及令牌的内容,具体取决于授权服务器。它不会影响监听程序的令牌验证规则。
    4
    (可选) Audience 检查。如果您的授权服务器提供 aud (audience)声明,并且您想要强制进行使用者检查,请将 ouath.check.audience 设置为 true。Audience 检查标识令牌的预期接收者。因此,Kafka 代理将拒绝在其 aud 声明中没有 clientId 的令牌。默认为 false
    5
    (可选)传递给令牌端点的 audience 参数。在获取用于代理身份验证的访问令牌时,需要使用 audience。它还在使用 clientIdsecret 的 PLAIN 客户端验证中用于 OAuth 2.0 的客户端名称。这只会影响获取令牌的能力,以及令牌的内容,具体取决于授权服务器。它不会影响监听程序的令牌验证规则。
    6
    有效的签发者 URI。只有此签发者发布的访问令牌才会被接受。(始终是必需的。)
    7
    Kafka 代理配置的客户端 ID,适用于所有代理。这是在 授权服务器中注册的客户端作为 kafka-broker。当内省端点用于令牌验证时,或使用 KeycloakAuthorizer 时是必需的。
    8
    Kafka 代理配置的 secret,适用于所有代理。当代理必须向授权服务器进行身份验证时,必须指定客户端 secret、访问令牌或刷新令牌。
    9
    (可选)连接到授权服务器时的连接超时(以秒为单位)。默认值为 60。
    10
    (可选)连接到授权服务器时的读取超时(以秒为单位)。默认值为 60。
    11
    将失败的 HTTP 请求重试到授权服务器的次数上限。默认值为 0,表示没有执行重试。要有效地使用这个选项,请考虑减少 oauth.connect.timeout.secondsoauth.read.timeout.seconds 选项的超时时间。但请注意,重试可能会阻止当前 worker 线程对其他请求使用,如果太多请求停滞,可能会导致 Kafka 代理无响应。
    12
    在尝试另一个失败 HTTP 请求重试到授权服务器前等待的时间。默认情况下,这段时间设为零,这意味着不会应用暂停。这是因为,导致失败请求的很多问题都是可快速解决的网络 glitches 或代理问题。但是,如果您的授权服务器处于压力或遇到高流量,您可能希望将此选项设置为 100 ms 或更高值,以减少服务器上的负载并增加成功重试的可能性。
    13
    JsonPath 查询,用于从 JWT 令牌或内省端点响应中提取组信息。默认情况下不设置。这可供自定义授权者根据用户组做出授权决策。
    14
    用于将组信息返回为单一分隔字符串时解析组的分隔符。默认值为 ','(comma)。
  5. 根据您如何应用 OAuth 2.0 身份验证以及所使用的授权服务器类型,添加额外的配置设置:

    listener.name.client.oauthbearer.sasl.jaas.config=org.apache.kafka.common.security.oauthbearer.OAuthBearerLoginModule required \
      # ...
      oauth.check.issuer=false \ 1
      oauth.fallback.username.claim="<client_id>" \ 2
      oauth.fallback.username.prefix="<client_account>" \ 3
      oauth.valid.token.type="bearer" \ 4
      oauth.userinfo.endpoint.uri="https://<oauth_server_address>/auth/realms/<realm_name>/protocol/openid-connect/userinfo" ; 5
    1
    如果您的授权服务器不提供 iss 声明,则无法执行签发者检查。在这种情况下,将 oauth.check.issuer 设置为 false,且不指定 oauth.valid.issuer.uri。默认为 true
    2
    授权服务器可能不会提供单个属性来标识常规用户和客户端。当客户端在其自己的名称中进行身份验证时,服务器可能会提供 客户端 ID。当用户使用用户名和密码进行身份验证时,若要获取刷新令牌或访问令牌,除了客户端 ID 外,服务器还提供 username 属性。使用此回退选项指定在主用户 ID 属性不可用时要使用的用户名声明(attribute)。如果需要,您可以使用 JsonPath 表达式,如 "['client.info'].['client.id']",从令牌中的嵌套 JSON 属性检索回退用户名。
    3
    当有 oauth.fallback.username.claim 时,可能还需要防止用户名声明的值和回退用户名声明之间的名称冲突。考虑存在名为 producer 的客户端,但也存在名为 producer 的普通用户。为了区分两者,您可以使用此属性向客户端的用户 ID 添加前缀。
    4
    (仅在使用 oauth.introspection.endpoint.uri)取决于您使用的授权服务器时,内省端点可能或可能无法返回 令牌 type 属性,或者可能包含不同的值。您可以指定来自内省端点必须包含的有效令牌类型值。
    5
    (仅在使用 oauth.introspection.endpoint.uri)时,可以配置或实施授权服务器,以便在内省端点响应中不提供任何可识别的信息。要获得用户 ID,您可以将 userinfo 端点的 URI 配置为回退。oauth.fallback.username.claimoauth.fallback.username.claimoauth.fallback.username.prefix 设置应用到 userinfo 端点的响应。
6.4.9.6.3. 配置 Kafka Java 客户端以使用 OAuth 2.0

配置 Kafka producer 和消费者 API,以使用 OAuth 2.0 与 Kafka 代理交互。在您的客户端 pom.xml 文件中添加回调插件,然后为 OAuth 2.0 配置客户端。

在客户端配置中指定以下内容:

  • SASL (简单身份验证和安全层)安全协议:

    • SASL_SSL 用于通过 TLS 加密连接进行身份验证
    • SASL_PLAINTEXT 用于通过未加密的连接进行身份验证

      SASL_SSL 用于生产环境,并且 SASL_PLAINTEXT 仅用于本地开发。使用 SASL_SSL 时,需要额外的 ssl.truststore 配置。安全连接(https://)与 OAuth 2.0 授权服务器需要 truststore 配置。要验证 OAuth 2.0 授权服务器,请将授权服务器的 CA 证书添加到客户端配置的信任存储中。您可以使用 PEM 或 PKCS #12 格式配置信任存储。

  • Kafka SASL 机制:

    • OAUTHBEARER 用于使用 bearer 令牌的凭证交换
    • PLAIN 传递客户端凭证(clientId + secret)或访问令牌
  • 实现 SASL 机制的 JAAS (Java 身份验证和授权服务)模块:

    • org.apache.kafka.common.security.oauthbearer.OAuthBearerLoginModule 实现 OAUTHBEARER 机制
    • org.apache.kafka.common.security.plain.PlainLoginModule 实现 PLAIN 机制
  • SASL 验证方法,它支持以下验证方法:

    • OAuth 2.0 客户端凭证
    • OAuth 2.0 密码授权(已弃用)
    • 访问令牌
    • 刷新令牌

添加 SASL 身份验证属性作为 JAAS 配置(sasl.jaas.config)。如何配置身份验证属性取决于您用于访问 OAuth 2.0 授权服务器的身份验证方法。在此过程中,属性在属性文件中指定,然后加载到客户端配置中。

注意

您还可以将身份验证属性指定为环境变量,或作为 Java 系统属性指定。对于 Java 系统属性,您可以使用 setProperty 设置它们,并使用 -D 选项在命令行中传递它们。

先决条件

  • AMQ Streams 和 Kafka 正在运行
  • 为 OAuth 访问 Kafka 代理部署并配置 OAuth 2.0 授权服务器
  • 为 OAuth 2.0 配置 Kafka 代理

流程

  1. 将带有 OAuth 2.0 支持的客户端库添加到 Kafka 客户端的 pom.xml 文件中:

    <dependency>
     <groupId>io.strimzi</groupId>
     <artifactId>kafka-oauth-client</artifactId>
     <version>0.13.0.redhat-00008</version>
    </dependency>
  2. 通过在属性文件中指定以下配置来配置客户端属性:

    • 安全协议
    • SASL 机制
    • JAAS 模块和身份验证属性,具体取决于所使用的方法

      例如,我们可以将以下内容添加到 client.properties 文件中:

      客户端凭证机制属性

      security.protocol=SASL_SSL 1
      sasl.mechanism=OAUTHBEARER 2
      ssl.truststore.location=/tmp/truststore.p12 3
      ssl.truststore.password=$STOREPASS
      ssl.truststore.type=PKCS12
      sasl.jaas.config=org.apache.kafka.common.security.oauthbearer.OAuthBearerLoginModule required \
        oauth.token.endpoint.uri="<token_endpoint_url>" \ 4
        oauth.client.id="<client_id>" \ 5
        oauth.client.secret="<client_secret>" \ 6
        oauth.ssl.truststore.location="/tmp/oauth-truststore.p12" \ 7
        oauth.ssl.truststore.password="$STOREPASS" \ 8
        oauth.ssl.truststore.type="PKCS12" \ 9
        oauth.scope="<scope>" \ 10
        oauth.audience="<audience>" ; 11

      1
      TLS 加密连接的 SASL_SSL 安全协议。仅对本地开发使用 SASL_PLAINTEXT 来进行本地开发。
      2
      SASL 机制指定为 OAUTHBEARERPLAIN
      3
      用于安全访问 Kafka 集群的信任存储配置。
      4
      授权服务器令牌端点的 URI。
      5
      客户端 ID,这是在授权服务器中创建客户端时使用的名称。
      6
      在授权服务器中创建 客户端 时创建的客户端 secret。
      7
      位置包含授权服务器的公钥证书(truststore.p12)。
      8
      用于访问 truststore 的密码。
      9
      truststore 类型。
      10
      (可选)从令牌端点请求令牌的范围。授权服务器可能需要客户端指定范围。
      11
      (可选)从令牌端点请求令牌的听众。授权服务器可能需要客户端指定使用者。

      密码授予机制属性

      security.protocol=SASL_SSL
      sasl.mechanism=OAUTHBEARER
      ssl.truststore.location=/tmp/truststore.p12
      ssl.truststore.password=$STOREPASS
      ssl.truststore.type=PKCS12
      sasl.jaas.config=org.apache.kafka.common.security.oauthbearer.OAuthBearerLoginModule required \
        oauth.token.endpoint.uri="<token_endpoint_url>" \
        oauth.client.id="<client_id>" \ 1
        oauth.client.secret="<client_secret>" \ 2
        oauth.password.grant.username="<username>" \ 3
        oauth.password.grant.password="<password>" \ 4
        oauth.ssl.truststore.location="/tmp/oauth-truststore.p12" \
        oauth.ssl.truststore.password="$STOREPASS" \
        oauth.ssl.truststore.type="PKCS12" \
        oauth.scope="<scope>" \
        oauth.audience="<audience>" ;

      1
      客户端 ID,这是在授权服务器中创建客户端时使用的名称。
      2
      (可选)在授权服务器中创建客户端时创建的客户端 secret。
      3
      password 授权身份验证的用户名。OAuth 密码授权配置(用户名和密码)使用 OAuth 2.0 密码授权方法。要使用密码授权,请在您的授权服务器上为客户端创建一个有限权限的用户帐户。帐户应像服务帐户一样操作。在进行身份验证需要用户帐户的环境中使用,但首先考虑使用刷新令牌。
      4
      密码以授予密码身份验证。
      注意

      SASL PLAIN 不支持使用 OAuth 2.0 密码授权方法传递用户名和密码(密码授权)。

      访问令牌属性

      security.protocol=SASL_SSL
      sasl.mechanism=OAUTHBEARER
      ssl.truststore.location=/tmp/truststore.p12
      ssl.truststore.password=$STOREPASS
      ssl.truststore.type=PKCS12
      sasl.jaas.config=org.apache.kafka.common.security.oauthbearer.OAuthBearerLoginModule required \
        oauth.token.endpoint.uri="<token_endpoint_url>" \
        oauth.access.token="<access_token>" ; 1
        oauth.ssl.truststore.location="/tmp/oauth-truststore.p12" \
        oauth.ssl.truststore.password="$STOREPASS" \
        oauth.ssl.truststore.type="PKCS12" \

      1
      Kafka 客户端的长期访问令牌。

      刷新令牌属性

      security.protocol=SASL_SSL
      sasl.mechanism=OAUTHBEARER
      ssl.truststore.location=/tmp/truststore.p12
      ssl.truststore.password=$STOREPASS
      ssl.truststore.type=PKCS12
      sasl.jaas.config=org.apache.kafka.common.security.oauthbearer.OAuthBearerLoginModule required \
        oauth.token.endpoint.uri="<token_endpoint_url>" \
        oauth.client.id="<client_id>" \ 1
        oauth.client.secret="<client_secret>" \ 2
        oauth.refresh.token="<refresh_token>" ; 3
        oauth.ssl.truststore.location="/tmp/oauth-truststore.p12" \
        oauth.ssl.truststore.password="$STOREPASS" \
        oauth.ssl.truststore.type="PKCS12" \

      1
      客户端 ID,这是在授权服务器中创建客户端时使用的名称。
      2
      (可选)在授权服务器中创建客户端时创建的客户端 secret。
      3
      Kafka 客户端的长期刷新令牌。
  3. 在 Java 客户端代码中输入 OAUTH 2.0 身份验证的客户端属性。

    显示客户端属性输入示例

    Properties props = new Properties();
    try (FileReader reader = new FileReader("client.properties", StandardCharsets.UTF_8)) {
      props.load(reader);
    }

  4. 验证 Kafka 客户端能否访问 Kafka 代理。

6.4.10. 使用基于 OAuth 2.0 令牌的授权

如果您在 Red Hat Single Sign-On 中使用 OAuth 2.0 进行基于令牌的身份验证,您还可以使用 Red Hat Single Sign-On 配置授权规则来限制客户端访问 Kafka 代理。身份验证建立用户身份。授权决定该用户的访问权限级别。

AMQ Streams 支持通过 Red Hat Single Sign-On Authorization Services 使用基于 OAuth 2.0 令牌的授权,它允许您集中管理安全策略和权限。

Red Hat Single Sign-On 中定义的安全策略和权限用于授予对 Kafka 代理上资源的访问权限。用户和客户端与允许对 Kafka 代理执行特定操作的策略进行匹配。

Kafka 允许所有用户默认对代理进行完全访问,同时还提供 AclAuthorizer 插件来配置基于 Access Control Lists (ACL)的授权。

ZooKeeper 存储 ACL 规则,该规则根据 用户名 授予或拒绝对资源的访问。但是,红帽单点登录基于 OAuth 2.0 令牌的授权在您希望实现对 Kafka 代理的访问控制方面具有更大的灵活性。另外,您可以将 Kafka 代理配置为使用 OAuth 2.0 授权和 ACL。

6.4.10.1. OAuth 2.0 授权机制

AMQ Streams 中的 OAuth 2.0 授权使用红帽单点登录服务器授权服务 REST 端点,通过在特定用户上应用定义的安全策略来扩展基于令牌的身份验证,并为该用户提供授予不同资源的权限列表。策略使用角色和组来匹配用户的权限。OAuth 2.0 授权根据从 Red Hat Single Sign-On Authorization Services 用户获得的授予者列表在本地强制实施权限。

6.4.10.1.1. Kafka 代理自定义授权器

AMQ Streams 提供了一个 Red Hat Single Sign-On authorizer (KeycloakAuthorizer)。为了对 Red Hat Single Sign-On 提供的授权服务使用 Red Hat Single Sign-On REST 端点,您可以在 Kafka 代理上配置自定义授权程序。

授权程序根据需要从授权服务器获取授予权限的列表,并在 Kafka Broker 上本地强制实施授权,为每个客户端请求做出快速授权决策。

6.4.10.2. 配置 OAuth 2.0 授权支持

这个步骤描述了如何使用 Red Hat Single Sign-On Authorization Services 将 Kafka 代理配置为使用 OAuth 2.0 授权服务。

开始前

考虑某些用户所需的访问权限或希望限制某些用户。您可以使用 Red Hat Single Sign-On 角色客户端 和用户 的组合在 Red Hat Single Sign-On 中配置访问权限。

通常,组用于根据机构部门或地理位置匹配用户。和 角色用于根据其功能匹配用户。

使用红帽单点登录,您可以在 LDAP 中存储用户和组,而客户端和角色不能以这种方式存储。在选择配置授权策略时,对用户数据的存储和访问可能是如何配置授权策略的因素。

注意

无论在 Kafka 代理上实现的授权是什么,超级用户始终对 Kafka 代理具有不受限制的访问。

先决条件

  • AMQ Streams 必须通过 Red Hat Single Sign-On 配置为使用 OAuth 2.0 进行基于令牌的身份验证。设置授权时,您可以使用相同的 Red Hat Single Sign-On 服务器端点。
  • 您需要了解如何管理红帽单点登录授权服务的策略和权限,如 Red Hat Single Sign-On 文档所述

流程

  1. 访问 Red Hat Single Sign-On Admin 控制台,或使用 Red Hat Single Sign-On Admin CLI 为设置 OAuth 2.0 身份验证时创建的 Kafka 代理客户端启用授权服务。
  2. 使用授权服务为客户端定义资源、授权范围、策略和权限。
  3. 通过分配角色和组,将权限绑定到用户和客户端。
  4. 将 Kafka 代理配置为使用 Red Hat Single Sign-On 授权。

    在 Kafka server.properties 配置文件中添加以下内容,以便在 Kafka 中安装授权器:

    authorizer.class.name=io.strimzi.kafka.oauth.server.authorizer.KeycloakAuthorizer
    principal.builder.class=io.strimzi.kafka.oauth.server.OAuthKafkaPrincipalBuilder
  5. 添加 Kafka 代理的配置以访问授权服务器和授权服务器。

    在此我们显示作为额外属性添加到 server.properties 的示例配置,但您也可以使用大写或大写的命名规则将它们定义为环境变量。

    strimzi.authorization.token.endpoint.uri="https://<auth_server_address>/auth/realms/REALM-NAME/protocol/openid-connect/token" 1
    strimzi.authorization.client.id="kafka" 2
    1
    到 Red Hat Single Sign-On 的 OAuth 2.0 令牌端点 URL。对于生产环境,始终使用 https:// urls。
    2
    Red Hat Single Sign-On 中启用了授权服务的 OAuth 2.0 客户端定义的客户端 ID。通常,kafka 用作 ID。
  6. (可选)为特定 Kafka 集群添加配置。

    例如:

    strimzi.authorization.kafka.cluster.name="kafka-cluster" 1
    1
    特定 Kafka 集群的名称。名称用于目标权限,从而能够管理同一 Red Hat Single Sign-On 域中的多个集群。默认值为 kafka-cluster
  7. (可选)到 simple 授权。

    例如:

    strimzi.authorization.delegate.to.kafka.acl="false" 1
    1
    如果 Red Hat Single Sign-On Authorization Services 策略无法访问,将授权委派给 Kafka AclAuthorizer。默认值为 false
  8. (可选)为授权服务器添加 TLS 连接的配置。

    例如:

    strimzi.authorization.ssl.truststore.location=<path_to_truststore> 1
    strimzi.authorization.ssl.truststore.password=<my_truststore_password> 2
    strimzi.authorization.ssl.truststore.type=JKS 3
    strimzi.authorization.ssl.secure.random.implementation=SHA1PRNG 4
    strimzi.authorization.ssl.endpoint.identification.algorithm=HTTPS 5
    1
    包含证书的信任存储的路径。
    2
    truststore 的密码。
    3
    truststore 类型。如果没有设置,则使用默认的 Java 密钥存储类型。
    4
    随机数生成器实施。如果没有设置,则使用 Java 平台 SDK 默认。
    5
    主机名验证。如果设置为空字符串,则主机名验证将关闭。如果没有设置,则默认值为 HTTPS,它会强制对服务器证书进行主机名验证。
  9. (可选)配置从授权服务器刷新授权。授予刷新任务通过枚举活跃令牌并请求每个令牌的最新授予来工作。

    例如:

    strimzi.authorization.grants.refresh.period.seconds="120" 1
    strimzi.authorization.grants.refresh.pool.size="10" 2
    strimzi.authorization.grants.max.idle.time.seconds="300" 3
    strimzi.authorization.grants.gc.period.seconds="300" 4
    strimzi.authorization.reuse.grants="false" 5
    1
    指定授权服务器的授予的频率(默认为每分钟一次)。要关闭刷新以进行调试目的,可设置为 "0"
    2
    指定授予刷新作业使用的线程池大小(并行级别)。默认值为 "5"
    3
    缓存中闲置授权的时间(以秒为单位)。默认值为 300。
    4
    连续运行作业之间的时间(以秒为单位)。默认值为 300。
    5
    控制是否为新会话获取最新的授权。禁用后,从 Red Hat Single Sign-On 检索并缓存该用户的权限。默认值为 true
  10. (可选)与授权服务器通信时配置网络超时。

    例如:

    strimzi.authorization.connect.timeout.seconds="60" 1
    strimzi.authorization.read.timeout.seconds="60" 2
    strimzi.authorization.http.retries="2" 3
    1
    连接到 Red Hat Single Sign-On 令牌端点时的连接超时(以秒为单位)。默认值为 60
    2
    连接到 Red Hat Single Sign-On 令牌端点时的读取超时(以秒为单位)。默认值为 60
    3
    对授权服务器失败的 HTTP 请求重试(不暂停)的最大次数。默认值为 0, 表示没有执行重试。要有效地使用这个选项,请考虑减少 strimzi.authorization.connect.timeout.secondsstrimzi.authorization.read.timeout.seconds 选项的超时时间。但请注意,重试可能会阻止当前 worker 线程对其他请求使用,如果太多请求停滞,可能会导致 Kafka 代理无响应。
  11. (可选)为令牌验证和授权启用 OAuth 2.0 指标。

    例如:

    oauth.enable.metrics="true" 1
    1
    控制是否启用或禁用 OAuth 指标。默认值为 false
  12. 通过以客户端或具有特定角色的用户访问 Kafka 代理来验证配置的权限,确保它们具有必要的访问权限,或者没有应该具有访问权限。

6.4.11. 使用基于 OPA 策略的授权

开源策略代理(OPA)是一个开源策略引擎。您可以将 OPA 与 AMQ Streams 集成,作为基于策略的授权机制,允许在 Kafka 代理上进行客户端操作。

从客户端发出请求时,OPA 将根据为 Kafka 访问定义的策略评估请求,然后允许或拒绝请求。

注意

红帽不支持 OPA 服务器。

6.4.11.1. 定义 OPA 策略

在将 OPA 与 AMQ Streams 集成前,请考虑如何定义策略以提供精细的访问控制。

您可以为 Kafka 集群、消费者组和主题定义访问控制。例如,您可以定义一个授权策略,允许从制作者客户端写入到特定代理主题的访问。

因此,策略可能会指定:

  • 与制作者客户端关联的用户主体主机地址
  • 客户端允许的操作
  • 策略适用的 资源类型 (topic)和资源名称

允许或拒绝决策将写入到策略中,并根据提供的请求和客户端识别数据提供响应。

在我们的示例中,生产者客户端必须满足策略才能写入该主题。

6.4.11.2. 连接到 OPA

要启用 Kafka 访问 OPA 策略引擎以查询访问控制策略,您可以在您的 Kafka server.properties 文件中配置自定义 OPA authorizer 插件 (kafka-authorizer-opa-VERSION.jar)。

客户端发出请求时,OPA 策略引擎将通过指定的 URL 地址和 REST 端点来查询 OPA 策略引擎,该端点必须是定义的策略的名称。

该插件提供了客户端请求的详细信息 - 用户主体、操作和资源 - 以 JSON 格式针对策略进行检查。详细信息将包括客户端的唯一身份;例如,使用 TLS 身份验证时将区分名称与客户端证书进行区分。

OPA 使用数据向插件提供响应 - truefalse - 允许或拒绝请求。

6.4.11.3. 配置 OPA 授权支持

这个步骤描述了如何将 Kafka 代理配置为使用 OPA 授权。

开始前

考虑某些用户所需的访问权限或希望限制某些用户。您可以使用 用户和 Kafka 资源 的组合来定义 OPA 策略。

可以设置 OPA 从 LDAP 数据源加载用户信息。

注意

无论在 Kafka 代理上实现的授权是什么,超级用户始终对 Kafka 代理具有不受限制的访问。

先决条件

流程

  1. 编写授权客户端请求以便在 Kafka 代理执行操作所需的 OPA 策略。

    请参阅 定义 OPA 策略

    现在,将 Kafka 代理配置为使用 OPA。

  2. 为 Kafka 安装 OPA 授权插件

    请参阅 连接到 OPA

    确保插件文件包含在 Kafka classpath 中。

  3. 在 Kafka server.properties 配置文件中添加以下内容以启用 OPA 插件:

    authorizer.class.name: com.bisnode.kafka.authorization.OpaAuthorizer
  4. 向 Kafka 代理的 server.properties 中添加进一步的配置,以访问 OPA 策略引擎和策略。

    例如:

    opa.authorizer.url=https://OPA-ADDRESS/allow 1
    opa.authorizer.allow.on.error=false 2
    opa.authorizer.cache.initial.capacity=50000 3
    opa.authorizer.cache.maximum.size=50000 4
    opa.authorizer.cache.expire.after.seconds=600000 5
    super.users=User:alice;User:bob 6
    1
    (必需)授权器插件将查询的策略的 OAuth 2.0 令牌端点 URL。在本例中,策略称为 allow
    2
    标志指定在授权器插件无法与 OPA 策略引擎连接时,默认是否允许或拒绝客户端访问。
    3
    本地缓存的初始容量(以字节为单位)。使用缓存,以便插件不必为每个请求查询 OPA 策略引擎。
    4
    本地缓存的最大容量(以字节为单位)。
    5
    通过从 OPA 策略引擎重新加载来刷新本地缓存的时间(毫秒)。
    6
    被视为超级用户的用户主体列表,以便在不查询 Open Policy Agent 策略的情况下始终允许它们。

    有关身份验证和授权选项的详情,请参考 Open Policy Agent 网站

  5. 使用具有且没有正确授权的客户端访问 Kafka 代理来验证配置的权限。

第 7 章 创建和管理主题

Kafka 中的消息总是发送到或从主题接收。本章论述了如何创建和管理 Kafka 主题。

7.1. 分区和副本

Kafka 中的消息总是发送到或从主题接收。主题始终分成一个或多个分区。分区充当分片。这意味着制作者发送的每个消息始终写入到单个分区中。由于将消息分片到不同的分区,因此主题易于横向扩展。

每个分区都可以有一个或多个副本,这些副本将存储在集群中的不同代理中。在创建主题时,您可以使用 复制因子 配置副本数量。复制因素 定义集群中要保留的副本数。给定分区的一个副本将选为领导分区。领导副本由生产者用于发送新消息并供消费者使用消息。其他副本将遵循副本。遵循者复制领导者。

如果领导失败,则后续者之一将自动成为新的领导。每个服务器充当其部分分区的领导者,对其他分区的遵循,因此负载在群集内取得良好平衡。

注意

复制因素决定了副本数,包括领导者和后续者。例如,如果您将复制项设置为 3,那么将有一个领导和两个后续副本。

7.2. 消息保留

消息保留策略定义了信息存储在 Kafka 代理中的时长。它可以根据时间、分区大小或两者定义。

例如,您可以定义消息应保留:

  • 7 天
  • 直到 parition 具有 1GB 信息。达到限制后,会删除最旧的消息。
  • 7 天或直到达到 1GB 限制。首先将使用任何限制。
警告

Kafka 代理将信息存储在日志片段中。只有在创建新的日志片段时,才会删除过去保留策略的消息。当以前的日志片段超过配置的日志片段大小时,会创建新的日志片段。此外,用户可以请求定期创建新的片段。

另外,Kafka 代理支持紧凑策略。

对于带有紧凑策略的主题,代理总是为每个键保留最后一条消息。具有相同密钥的旧消息将从分区中删除。因为 compact 是一个定期执行的操作,所以当具有相同键的新消息发送到分区时不会立即发生。相反,可能需要稍等片刻,直到旧的消息被删除为止。

有关消息保留配置选项的详情,请参考 第 7.5 节 “主题配置”

7.3. 主题自动创建

当生成者或消费者尝试从不存在的主题发送消息时,Kafka 默认会自动创建该主题。这个行为由 auto.create.topics.enable 配置属性控制,该属性默认设置为 true

要禁用它,在 Kafka 代理配置文件中将 auto.create.topics.enable 设置为 false

auto.create.topics.enable=false

7.4. 删除主题

Kafka 提供了禁用删除主题的可能性。这通过 delete.topic.enable 属性进行配置,默认设为 true (即,删除主题是可能的)。当此属性设置为 false 时,将无法删除主题,所有尝试删除主题都将返回成功,但主题不会被删除。

delete.topic.enable=false

7.5. 主题配置

自动创建的主题将使用默认主题配置,可在代理属性文件中指定。但是,在手动创建主题时,可以在创建时指定其配置。也可以在创建后更改主题的配置。手动创建的主题的主要主题配置选项有:

cleanup.policy
配置保留策略 以删除或压缩 删除策略 将删除旧的记录。紧凑 策略将启用日志压缩。默认值为 delete。有关日志压缩的更多信息,请参阅 Kafka 网站
compression.type
指定用于存储消息的压缩。有效值为 gzipsnappylz4、 未压缩 (无压缩)和 制作者 (包含制作者使用的压缩 codec)。默认值为 producer
max.message.bytes
Kafka 代理允许的消息的最大大小,以字节为单位。默认值为 1000012
min.insync.replicas
必须同步的最小副本数才能被视为成功。默认值为:1
retention.ms
保留日志片段的最大毫秒数。早于这个值的日志片段将被删除。默认值为 604800000 (7 天)。
retention.bytes
分区要保留的最大字节数。当分区大小超过这个限制后,会删除最旧的日志片段。-1 表示没有限制。默认值为 -1
segment.bytes
单个提交日志段文件的最大大小(以字节为单位)。当片段达到其大小时,将启动新的片段。默认值为 1073741824 字节 (1 gibibyte)。

自动创建的主题的默认值可使用类似的选项在 Kafka 代理配置中指定:

log.cleanup.policy
请参阅上面的 cleanup.policy
compression.type
请参阅上述 compression.type
message.max.bytes
请参阅上面的 max.message.bytes
min.insync.replicas
请参阅上面的 min.insync.replicas
log.retention.ms
请参阅上面的 retention.ms
log.retention.bytes
请参阅上面的 retention.bytes
log.segment.bytes
请参阅上面的 segment.bytes
default.replication.factor
自动创建主题的默认复制因素。默认值为 1
num.partitions
自动创建主题的默认分区数。默认值为 1

7.6. 内部主题

内部主题由 Kafka 代理和客户端在内部创建和使用。Kafka 有几个内部主题。它们用于存储消费者偏移(__consumer_offsets)或事务状态(__transaction_state)。这些主题可使用以前缀 offsets.topic.transaction.state.log. 开头的专用 Kafka 代理配置选项来配置。最重要的配置选项有:

offsets.topic.replication.factor
__consumer_offsets 主题的副本数。默认值为 3
offsets.topic.num.partitions
__consumer_offsets 主题的分区数。默认值为 50
transaction.state.log.replication.factor
__transaction_state 主题的副本数。默认值为 3
transaction.state.log.num.partitions
__transaction_state 主题的分区数。默认值为 50
transaction.state.log.min.isr
必须确认写入 __transaction_state 主题的最小副本数才被视为成功。如果无法满足这个最小值,则制作者将失败,并出现例外。默认值为 2

7.7. 创建主题

使用 kafka-topics.sh 工具来管理主题。Kafka-topics.sh 是 AMQ Streams 发行版本的一部分,可在 bin 目录中找到。

先决条件

  • AMQ Streams 集群已安装并运行

创建主题

  1. 使用 kafka-topics.sh 实用程序创建主题并指定以下内容:

    • --bootstrap-server 选项中的 Kafka 代理的主机和端口。
    • 要在 --create 选项中创建新主题。
    • --topic 选项中的主题名称。
    • --partitions 选项中的分区数量。
    • --replication-factor 选项中的主题复制因素。

      您还可以使用 --config 选项覆盖一些默认主题配置选项。这个选项可多次使用来覆盖不同的选项。

      /opt/kafka/bin/kafka-topics.sh --bootstrap-server <broker_address> --create --topic <TopicName> --partitions <NumberOfPartitions> --replication-factor <ReplicationFactor> --config <Option1>=<Value1> --config <Option2>=<Value2>

      创建名为 mytopic的主题的命令示例

      /opt/kafka/bin/kafka-topics.sh --bootstrap-server localhost:9092 --create --topic mytopic --partitions 50 --replication-factor 3 --config cleanup.policy=compact --config min.insync.replicas=2

  2. 使用 kafka-topics.sh 验证主题是否存在。

    /opt/kafka/bin/kafka-topics.sh --bootstrap-server <broker_address> --describe --topic <TopicName>

    描述名为 mytopic的主题的命令示例

    /opt/kafka/bin/kafka-topics.sh --bootstrap-server localhost:9092 --describe --topic mytopic

其他资源

7.8. 列出和描述主题

kafka-topics.sh 工具可以用来列出和描述主题。kafka-topics.sh 是 AMQ Streams 发行版本的一部分,可在 bin 目录中找到。

先决条件

  • AMQ Streams 集群已安装并运行
  • 存在主题 mytopic

描述主题

  1. 使用 kafka-topics.sh 实用程序描述主题,并指定以下内容:

    • --bootstrap-server 选项中的 Kafka 代理的主机和端口。
    • 使用 --describe 选项指定您要描述主题。
    • 主题名称必须在 --topic 选项指定。
    • 当省略 --topic 选项时,它将描述所有可用的主题。

      /opt/kafka/bin/kafka-topics.sh --bootstrap-server <broker_address> --describe --topic <TopicName>

      描述名为 mytopic的主题的命令示例

      /opt/kafka/bin/kafka-topics.sh --bootstrap-server localhost:9092 --describe --topic mytopic

      命令列出属于此主题的所有分区和副本。它还列出所有主题配置选项。

7.9. 修改主题配置

kafka-configs.sh 工具可以用来修改主题配置。kafka-configs.sh 是 AMQ Streams 发行版本的一部分,可在 bin 目录中找到。

先决条件

  • AMQ Streams 集群已安装并运行
  • 存在主题 mytopic

修改主题配置

  1. 使用 kafka-configs.sh 工具获取当前的配置。

    • --bootstrap-server 选项指定 Kafka 代理的主机和端口。
    • --entity-type 设置为 topic,将 --entity-name 设置为主题的名称。
    • 使用 --describe 选项获取当前的配置。

      /opt/kafka/bin/kafka-configs.sh --bootstrap-server <broker_address> --entity-type topics --entity-name <TopicName> --describe

      获取名为 mytopic的主题配置的命令示例

      /opt/kafka/bin/kafka-configs.sh --bootstrap-server localhost:9092 --entity-type topics --entity-name mytopic --describe

  2. 使用 kafka-configs.sh 工具更改配置。

    • --bootstrap-server 选项指定 Kafka 代理的主机和端口。
    • --entity-type 设置为 topic,将 --entity-name 设置为主题的名称。
    • 使用 --alter 选项修改当前的配置。
    • --add-config 选项指定您要添加或更改的选项。

      /opt/kafka/bin/kafka-configs.sh --bootstrap-server <broker_address> --entity-type topics --entity-name <TopicName> --alter --add-config <Option>=<Value>

      更改名为 mytopic的主题配置的命令示例

      /opt/kafka/bin/kafka-configs.sh --bootstrap-server localhost:9092 --entity-type topics --entity-name mytopic --alter --add-config min.insync.replicas=1

  3. 使用 kafka-configs.sh 工具删除现有配置选项。

    • --bootstrap-server 选项指定 Kafka 代理的主机和端口。
    • --entity-type 设置为 topic,将 --entity-name 设置为主题的名称。
    • 使用 --delete-config 选项删除现有配置选项。
    • 指定在 --remove-config 选项中删除的选项。

      /opt/kafka/bin/kafka-configs.sh --bootstrap-server <broker_address> --entity-type topics --entity-name <TopicName> --alter --delete-config <Option>

      更改名为 mytopic的主题配置的命令示例

      /opt/kafka/bin/kafka-configs.sh --bootstrap-server localhost:9092 --entity-type topics --entity-name mytopic --alter --delete-config min.insync.replicas

7.10. 删除主题

kafka-topics.sh 工具可用于管理主题。kafka-topics.sh 是 AMQ Streams 发行版本的一部分,可在 bin 目录中找到。

先决条件

  • AMQ Streams 集群已安装并运行
  • 存在主题 mytopic

删除主题

  1. 使用 kafka-topics.sh 工具删除主题。

    • --bootstrap-server 选项中的 Kafka 代理的主机和端口。
    • 使用 --delete 选项指定应删除现有主题。
    • 主题名称必须在 --topic 选项指定。

      /opt/kafka/bin/kafka-topics.sh --bootstrap-server <broker_address> --delete --topic <TopicName>

      创建名为 mytopic的主题的命令示例

      /opt/kafka/bin/kafka-topics.sh --bootstrap-server localhost:9092 --delete --topic mytopic

  2. 使用 kafka-topics.sh 验证主题是否已删除。

    /opt/kafka/bin/kafka-topics.sh --bootstrap-server <broker_address> --list

    列出所有主题的命令示例

    /opt/kafka/bin/kafka-topics.sh --bootstrap-server localhost:9092 --list

其他资源

第 8 章 在 Kafka Connect 中使用 AMQ Streams

使用 Kafka Connect 在 Kafka 和外部系统间流传输数据。Kafka Connect 提供了一个框架,用于移动大量数据,同时保持可扩展性和可靠性。Kafka Connect 通常用于将 Kafka 与 Kafka 集群外部的数据库、存储和消息传递系统集成。

Kafka Connect 以独立或分布式模式运行。

独立模式
在独立模式中,Kafka Connect 在单一节点上运行。独立模式用于开发和测试。
分布式模式
在分布式模式中,Kafka Connect 在一个或多个 worker 节点上运行,工作负载分布在其中。分布式模式主要用于生产环境。

Kafka Connect 使用为不同类型的外部系统实现连接的连接器插件。连接器插件有两种类型:sink 和 source。sink 连接器将数据从 Kafka 流传输到外部系统。源连接器将来自外部系统的数据流传输到 Kafka。

您还可以使用 Kafka Connect REST API 创建、管理和监控连接器实例。

连接器配置指定详情,如源或接收器连接器以及要从写入的 Kafka 主题。如何管理配置取决于您是否在独立或分布式模式下运行 Kafka 连接。

  • 在独立模式中,您可以通过 Kafka Connect REST API 将连接器配置作为 JSON 提供,也可以使用属性文件来定义配置。
  • 在分布式模式中,您只能通过 Kafka Connect REST API 将连接器配置作为 JSON 提供。

处理大量信息

您可以调整配置来处理大量信息。更多信息请参阅 第 11 章 处理大量信息

8.1. 在独立模式中使用 Kafka 连接

在 Kafka Connect 独立模式中,连接器与 Kafka Connect worker 进程在同一节点上运行,该进程在一个 JVM 中作为单个进程运行。这意味着 worker 进程和连接器共享相同的资源,如 CPU、内存和磁盘。

8.1.1. 在独立模式中配置 Kafka 连接

要在独立模式下配置 Kafka Connect,请编辑 config/connect-standalone.properties 配置文件。以下选项最重要的选项。

bootstrap.servers
用作 Kafka 的 bootstrap 连接的 Kafka 代理地址列表。例如,kafka0.my-domain.com:9092,kafka1.my-domain.com:9092,kafka2.my-domain.com:9092
key.converter
用于从 Kafka 格式转换消息密钥的类。例如,org.apache.kafka.connect.json.JsonConverter.
value.converter
用于从 Kafka 格式转换消息有效负载的类。例如,org.apache.kafka.connect.json.JsonConverter.
offset.storage.file.filename
指定在其中存储偏移数据的文件。

连接器插件使用 bootstrap 地址打开与 Kafka 代理的客户端连接。要配置这些连接,请使用以 producer.consumer. 为前缀的标准 Kafka producer 和使用者配置选项。

8.1.2. 在独立模式中运行 Kafka 连接

在独立模式中配置并运行 Kafka Connect。

先决条件

  • AMQ Streams 已安装,一个 Kafka 集群正在运行。
  • 您已在属性文件中指定了连接器配置。

    您还可以使用 Kafka Connect REST API 来管理连接器

流程

  1. 编辑 /opt/kafka/config/connect-standalone.properties Kafka 连接配置文件,并将 bootstrap.server 设置为指向您的 Kafka 代理。例如:

    bootstrap.servers=kafka0.my-domain.com:9092,kafka1.my-domain.com:9092,kafka2.my-domain.com:9092
  2. 使用配置文件启动 Kafka Connect,并指定一个或多个连接器配置。

    su - kafka
    /opt/kafka/bin/connect-standalone.sh /opt/kafka/config/connect-standalone.properties connector1.properties
    [connector2.properties ...]
  3. 验证 Kafka Connect 是否正在运行。

    jcmd | grep ConnectStandalone

8.2. 在分布式模式中使用 Kafka 连接

在分布式模式下,Kafka Connect 作为 worker 进程集群运行,每个 worker 在单独的节点上运行。连接器可以在集群中的任何 worker 上运行,从而提高了可扩展性和容错能力。连接器由 worker 管理,它会相互协调,以分发工作,并确保每个连接器在任何给定时间都在单个节点上运行。

8.2.1. 在分布式模式中配置 Kafka 连接

要在分布式模式下配置 Kafka Connect,请编辑 config/connect-distributed.properties 配置文件。以下选项最重要的选项。

bootstrap.servers
用作 Kafka 的 bootstrap 连接的 Kafka 代理地址列表。例如,kafka0.my-domain.com:9092,kafka1.my-domain.com:9092,kafka2.my-domain.com:9092
key.converter
用于从 Kafka 格式转换消息密钥的类。例如,org.apache.kafka.connect.json.JsonConverter.
value.converter
用于从 Kafka 格式转换消息有效负载的类。例如,org.apache.kafka.connect.json.JsonConverter.
group.id
分布式 Kafka Connect 集群的名称。这必须是唯一的,且不得与其他消费者组 ID 冲突。默认值为 connect-cluster
config.storage.topic
用于存储连接器配置的 Kafka 主题。默认值为 connect-configs
offset.storage.topic
用于存储偏移的 Kafka 主题。默认值为 connect-offset
status.storage.topic
用于 worker 节点状态的 Kafka 主题。默认值为 connect-status

AMQ Streams 在分布式模式下包括 Kafka Connect 的示例配置文件 - 请参阅 AMQ Streams 安装目录中的 config/connect-distributed.properties

连接器插件使用 bootstrap 地址打开与 Kafka 代理的客户端连接。要配置这些连接,请使用以 producer.consumer. 为前缀的标准 Kafka producer 和使用者配置选项。

8.2.2. 在分布式模式下运行 Kafka 连接

在分布式模式下运行 Kafka Connect。

先决条件

  • AMQ Streams 已安装,一个 Kafka 集群正在运行。

运行集群

  1. 编辑所有 Kafka Connect worker 节点上的 /opt/kafka/config/connect-distributed.properties Kafka Connect 配置文件。

    • bootstrap.server 选项设置为指向您的 Kafka 代理。
    • 设置 group.id 选项。
    • 设置 config.storage.topic 选项。
    • 设置 offset.storage.topic 选项。
    • 设置 status.storage.topic 选项。

      例如:

      bootstrap.servers=kafka0.my-domain.com:9092,kafka1.my-domain.com:9092,kafka2.my-domain.com:9092
      group.id=my-group-id
      config.storage.topic=my-group-id-configs
      offset.storage.topic=my-group-id-offsets
      status.storage.topic=my-group-id-status
  2. 在所有 Kafka Connect 节点上使用 /opt/kafka/config/connect-distributed.properties 配置文件启动 Kafka Connect worker。

    su - kafka
    /opt/kafka/bin/connect-distributed.sh /opt/kafka/config/connect-distributed.properties
  3. 验证 Kafka Connect 是否正在运行。

    jcmd | grep ConnectDistributed
  4. 使用 Kafka Connect REST API 管理连接器

8.3. 管理连接器

Kafka Connect REST API 提供了直接创建、更新和删除连接器的端点。您还可以使用 API 检查连接器的状态或更改日志级别。通过 API 创建连接器时,您可以提供连接器的配置详情作为 API 调用的一部分。

您还可以将连接器作为插件添加和管理。插件打包为 JAR 文件,该文件包含通过 Kafka Connect API 实现连接器的类。您只需要在 classpath 中指定插件,或将其添加到 Kafka Connect 的插件路径中,以便在启动时运行连接器插件。

除了使用 Kafka Connect REST API 或插件来管理连接器外,您还可以在以独立模式运行时使用属性文件添加连接器配置。要做到这一点,您可以在启动 Kafka Connect worker 进程时指定属性文件的位置。属性文件应包含连接器的配置详情,包括连接器类、源和目标主题,以及任何所需的身份验证或序列化设置。

8.3.1. 限制对 Kafka Connect API 的访问

Kafka Connect REST API 可以被经过身份验证访问权限的任何人访问,并知道端点 URL,其中包括主机名/IP 地址和端口号。仅将对 Kafka Connect API 的访问限制为可信用户,以防止未经授权的操作和潜在的安全问题。

为了提高安全性,我们建议为 Kafka Connect API 配置以下属性:

  • (Kafka 3.4 或更高版本) org.apache.kafka.disallowed.login.modules 以明确排除不安全的登录模块
  • connector.client.config.override.policy 设置为 NONE,以防止连接器配置覆盖 Kafka Connect 配置及其使用的用户和制作者

8.3.2. 配置连接器

使用 Kafka Connect REST API 或属性文件来创建、管理和监控连接器实例。在独立或分布式模式中使用 Kafka Connect 时,您可以使用 REST API。您可以在独立模式中使用 Kafka Connect 时使用属性文件。

8.3.2.1. 使用 Kafka Connect REST API 管理连接器

使用 Kafka Connect REST API 时,您可以通过向 Kafka Connect REST API 发送 PUTPOST HTTP 请求来动态创建连接器,在请求正文中指定连接器配置详情。

提示

使用 PUT 命令时,它与启动和更新连接器的命令相同。

REST 接口默认侦听端口 8083 并支持以下端点:

GET /connectors
返回现有连接器的列表。
POST /connectors
创建连接器。请求正文必须是带有连接器配置的 JSON 对象。
GET /connectors/<connector_name>
获取有关特定连接器的信息。
GET /connectors/<connector_name>/config
获取特定连接器的配置。
PUT /connectors/<connector_name>/config
更新特定连接器的配置。
GET /connectors/<connector_name>/status
获取特定连接器的状态。
GET /connectors/<connector_name>/tasks
获取特定连接器的任务列表
GET /connectors/<connector_name>/tasks/<task_id>/status
获取特定连接器的任务状态
PUT /connectors/<connector_name>/pause
暂停连接器及其所有任务。连接器将停止处理任何消息。
PUT /connectors/<connector_name>/resume
恢复暂停的连接器。
POST /connectors/<connector_name>/restart
在连接器失败时重启它。
POST /connectors/<connector_name>/tasks/<task_id>/restart
重启特定的任务。
DELETE /connectors/<connector_name>
删除连接器。
GET /connectors/<connector_name>/topics
获取特定连接器的主题。
PUT /connectors/<connector_name>/topics/reset
清空特定连接器的活跃主题集合。
GET /connector-plugins
获取所有支持的连接器插件的列表。
PUT /connector-plugins/<connector_type>/config/validate
验证连接器配置。

8.3.2.2. 指定连接器配置属性

要配置 Kafka Connect 连接器,您需要指定源或接收器连接器的配置详情。执行此操作有两种方法:通过 Kafka Connect REST API 使用 JSON 提供配置,或使用属性文件来定义配置属性。每种类型的连接器可用的特定配置选项可能会有所不同,但这两种方法都提供了指定所需设置的灵活方法。

以下选项适用于所有连接器:

name
连接器的名称,它在当前 Kafka Connect 实例中必须是唯一的。
connector.class
连接器插件的类。例如,org.apache.kafka.connect.file.FileStreamSinkConnector
tasks.max
指定连接器可以使用的最大任务数量。任务可让连接器并行执行工作。连接器可能会创建比指定更少的任务。
key.converter
用于从 Kafka 格式转换消息密钥的类。这会覆盖 Kafka Connect 配置设置的默认值。例如,org.apache.kafka.connect.json.JsonConverter.
value.converter
用于从 Kafka 格式转换消息有效负载的类。这会覆盖 Kafka Connect 配置设置的默认值。例如,org.apache.kafka.connect.json.JsonConverter.

必须至少为接收器连接器设置以下选项之一:

主题
用作输入的主题的逗号分隔列表。
topics.regex
用作输入的 Java 正则表达式。

有关所有其他选项,请参阅 Apache Kafka 文档中的 连接器属性。

注意

AMQ Streams 包括示例连接器配置文件 config/connect-file-sink.propertiesconfig/connect-file-source.properties

8.3.3. 使用 Kafka Connect API 创建连接器

使用 Kafka Connect REST API 创建用于 Kafka Connect 的连接器。

先决条件

  • Kafka Connect 安装。

流程

  1. 使用连接器配置准备 JSON 有效负载。例如:

    {
      "name": "my-connector",
      "config": {
      "connector.class": "org.apache.kafka.connect.file.FileStreamSinkConnector",
        "tasks.max": "1",
        "topics": "my-topic-1,my-topic-2",
        "file": "/tmp/output-file.txt"
      }
    }
  2. 发送 POST 请求到 <KafkaConnectAddress>:8083/connectors,以创建连接器。以下示例使用 curl

    curl -X POST -H "Content-Type: application/json" --data @sink-connector.json http://connect0.my-domain.com:8083/connectors
  3. 通过向 < KafkaConnectAddress > :8083/connectors 发送 GET 请求来验证连接器是否已部署。以下示例使用 curl

    curl http://connect0.my-domain.com:8083/connectors

8.3.4. 使用 Kafka Connect API 删除连接器

使用 Kafka Connect REST API 从 Kafka Connect 中删除连接器。

先决条件

  • Kafka Connect 安装。

删除连接器

  1. 通过向 <KafkaConnectAddress>:8083/connectors/<ConnectorName> 发送 GET 请求来验证连接器是否存在。以下示例使用 curl

    curl http://connect0.my-domain.com:8083/connectors
  2. 要删除连接器,请向 < KafkaConnectAddress>:8083/connectors 发送 DELETE 请求。以下示例使用 curl

    curl -X DELETE http://connect0.my-domain.com:8083/connectors/my-connector
  3. 通过向 < KafkaConnectAddress > :8083/connectors 发送 GET 请求来验证连接器是否已删除。以下示例使用 curl

    curl http://connect0.my-domain.com:8083/connectors

8.3.5. 添加连接器插件

Kafka 提供了示例连接器,用作开发连接器的起点。AMQ Streams 中包含以下示例连接器:

FileStreamSink
从 Kafka 主题读取数据并将数据写入文件中。
FileStreamSource
从文件中读取数据,并将数据发送到 Kafka 主题。

这两个连接器都包含在 libs/connect-file-<kafka_version>.redhat-<build>.jar 插件中。

要在 Kafka Connect 中使用连接器插件,您可以将其添加到 classpath 中,或者在 Kafka Connect 属性文件中指定插件路径,并将插件复制到该位置。

在 classpath 中指定示例连接器

CLASSPATH=/opt/kafka/libs/connect-file-<kafka_version>.redhat-<build>.jar opt/kafka/bin/connect-distributed.sh

设置插件路径

plugin.path=/opt/kafka/connector-plugins,/opt/connectors

plugin.path 配置选项可以包含以逗号分隔的路径列表。

如果需要,您可以添加更多连接器插件。Kafka Connect 会在启动时搜索并运行连接器插件。

注意

当在分布式模式下运行 Kafka Connect 时,必须在所有 worker 节点上提供插件。

第 9 章 在 MirrorMaker 2 中使用 AMQ Streams

使用 MirrorMaker 2 在两个或多个活跃 Kafka 集群之间复制数据,并在数据中心之间复制数据。

要配置 MirrorMaker 2,请编辑 config/connect-mirror-maker.properties 配置文件。如果需要,您可以为 MirrorMaker 2 启用分布式追踪

处理大量信息

您可以调整配置来处理大量信息。更多信息请参阅 第 11 章 处理大量信息

注意

MirrorMaker 2 具有之前版本的 MirrorMaker 不支持的功能。但是,您可以将 MirrorMaker 2 配置为在传统模式中使用

9.1. 配置主动/主动或主动/被动模式

您可以在 主动/被动或主动/主动 集群配置中 使用 MirrorMaker 2。

主动/主动集群配置
主动/主动配置有两个活跃集群,以双向方式复制数据。应用程序可以使用任一集群。每个集群都可以提供相同的数据。这样,您可以在不同的地理位置提供相同的数据。因为消费者组在两个集群中都活跃,复制主题的使用者偏移不会重新同步到源集群。
主动/被动集群配置
主动/被动配置具有将数据复制到被动集群的主动集群。被动集群保留在待机状态。在系统失败时,您可以使用被动集群进行数据恢复。

预期的结构是,生成者和消费者仅连接到活跃集群。每个目标目的地都需要一个 MirrorMaker 2 集群。

9.1.1. 双向复制(主动/主动)

MirrorMaker 2 架构支持 主动/主动 集群配置中的双向复制。

每个集群使用 sourceremote 主题的概念复制其他集群的数据。由于同一主题存储在每个集群中,所以远程主题由 MirrorMaker 2 重命名,以表示源集群。原始集群的名称前面是主题名称的前面。

图 9.1. 主题重命名

MirrorMaker 2 双向架构

通过标记原始集群,主题不会复制到该集群。

在配置需要数据聚合的架构时,通过 远程主题 复制的概念非常有用。使用者可以订阅同一集群中的源和目标主题,而无需单独的聚合集群。

9.1.2. 单向复制(active/passive)

MirrorMaker 2 架构支持 主动/被动 集群配置中的单向复制。

您可以使用 主动/被动集群 配置来备份或将数据迁移到另一个集群。在这种情况下,您可能不希望自动重命名远程主题。

您可以通过将 IdentityReplicationPolicy 添加到源连接器配置来覆盖自动重命名。应用此配置后,主题会保留其原始名称。

9.2. 配置 MirrorMaker 2 连接器

将 MirrorMaker 2 连接器配置用于编配 Kafka 集群之间的数据同步的内部连接器。

MirrorMaker 2 由以下连接器组成:

MirrorSourceConnector
源连接器将主题从源集群复制到目标集群。它还复制 ACL,且是 MirrorCheckpointConnector 才能运行所必需的。
MirrorCheckpointConnector
checkpoint 连接器定期跟踪偏移量。如果启用,它还在源和目标集群之间同步消费者组偏移。
MirrorHeartbeatConnector
heartbeat 连接器会定期检查源和目标集群之间的连接。

下表描述了连接器属性以及您配置为使用它们的连接器。

表 9.1. MirrorMaker 2 连接器配置属性

属性sourceConnectorcheckpointConnectorheartbeatConnector
admin.timeout.ms
管理任务的超时时间,如检测新主题。默认值为 60000 (1 分钟)。

replication.policy.class
定义远程主题命名约定的策略。默认为 org.apache.kafka.connect.mirror.DefaultReplicationPolicy

replication.policy.separator
目标集群中用于主题命名的分隔符。默认情况下,分隔符设置为点(.)。分隔符配置仅适用于 DefaultReplicationPolicy 复制策略类,用于定义远程主题名称。IdentityReplicationPolicy 类不使用属性,因为主题会保留其原始名称。

consumer.poll.timeout.ms
轮询源集群时的超时。默认值为 1000 (1 秒)。

 
offset-syncs.topic.location
offset-syncs 主题的位置,可以是 (默认)或 目标集群

 
topic.filter.class
选择要复制的主题的主题过滤器。默认为 org.apache.kafka.connect.mirror.DefaultTopicFilter

 
config.property.filter.class
要复制的主题配置属性的主题过滤器。默认为 org.apache.kafka.connect.mirror.DefaultConfigPropertyFilter

  
config.properties.exclude
不应复制的主题配置属性。支持以逗号分隔的属性名称和正则表达式。

  
offset.lag.max
同步远程分区前,允许的最大允许(不同步)偏移时间。默认值为 100

  
offset-syncs.topic.replication.factor
内部 offset-syncs 主题的复制因素。默认值为 3

  
refresh.topics.enabled
启用检查新主题和分区。默认为 true

  
refresh.topics.interval.seconds
主题刷新的频率。默认为 600 (10 分钟)。默认情况下,会每 10 分钟检查源集群中的新主题。您可以通过在源连接器配置中添加 refresh.topics.interval.seconds 来更改频率。

  
replication.factor
新主题的复制因素。默认值为 2

  
sync.topic.acls.enabled
启用源集群的 ACL 同步。默认为 true。如需更多信息,请参阅 第 9.5 节 “ACL 规则同步”

  
sync.topic.acls.interval.seconds
ACL 同步的频率。默认为 600 (10 分钟)。

  
sync.topic.configs.enabled
启用源集群的主题配置同步。默认为 true

  
sync.topic.configs.interval.seconds
主题配置同步的频率。默认 600 (10 分钟)。

  
checkpoints.topic.replication.factor
内部 检查点 主题的复制因素。默认值为 3
 

 
emit.checkpoints.enabled
启用将消费者偏移同步到目标集群。默认为 true
 

 
emit.checkpoints.interval.seconds
消费者偏移同步的频率。默认值为 60 (1 分钟)。
 

 
group.filter.class
选择要复制的消费者组的组过滤器。默认为 org.apache.kafka.connect.mirror.DefaultGroupFilter
 

 
refresh.groups.enabled
启用检查新的消费者组。默认为 true
 

 
refresh.groups.interval.seconds
消费者组刷新的频率。默认为 600 (10 分钟)。
 

 
sync.group.offsets.enabled
启用将消费者组偏移同步到目标集群 __consumer_offsets 主题。默认为 false
 

 
sync.group.offsets.interval.seconds
消费者组偏移同步的频率。默认值为 60 (1 分钟)。
 

 
emit.heartbeats.enabled
在目标集群中启用连接检查。默认为 true
  

emit.heartbeats.interval.seconds
连接检查的频率。默认为 1 ( 1 秒)。
  

heartbeats.topic.replication.factor
内部 心跳 主题的复制因素。默认值为 3
  

9.2.1. 更改消费者组偏移主题的位置

MirrorMaker 2 使用内部主题跟踪消费者组的偏移。

offset-syncs 主题
offset-syncs 主题映射复制主题元数据的源和目标偏移。
检查点 主题
checkpoints 主题映射源和目标集群中每个消费者组中复制主题分区的最后提交偏移量。

因为它们被 MirrorMaker 2 内部使用,所以您不会直接与这些主题交互。

MirrorCheckpointConnector 为偏移跟踪发出 检查点checkpoints 主题的偏移以预先决定的间隔通过配置进行跟踪。这两个主题都允许从故障转移的正确偏移位置完全恢复复制。

offset-syncs 主题的位置是 源集群。您可以使用 offset-syncs.topic.location 连接器配置将它更改为 目标集群。您需要对包含该主题的集群进行读/写访问权限。使用目标集群作为 offset-syncs 主题的位置,即使您只对源集群具有读取访问权限,您也可以使用 MirrorMaker 2。

9.2.2. 同步消费者组偏移

__consumer_offsets 主题存储各个消费者组的提交偏移信息。偏移同步会定期将源集群的消费者组的使用者偏移转移到目标集群的使用者偏移量中。

偏移同步在主动/被动配置中特别有用。如果主动集群停机,消费者应用程序可以切换到被动(standby)集群,并从最后一个传输的偏移位置获取。

要使用主题偏移同步,请通过将 sync.group.offsets.enabled 添加到检查点连接器配置来启用同步,并将属性设置为 true。同步默认为禁用。

在源连接器中使用 IdentityReplicationPolicy 时,还必须在检查点连接器配置中进行配置。这样可确保为正确的主题应用镜像的消费者偏移。

消费者偏移仅针对目标集群中未激活的消费者组同步。如果消费者组位于目标集群中,则无法执行同步,并返回 UNKNOWN_MEMBER_ID 错误。

如果启用,则会定期从源集群同步偏移。您可以通过在检查点连接器配置中添加 sync.group.offsets.interval.secondsemit.checkpoints.interval.seconds 来更改频率。属性指定同步消费者组偏移的频率,以及为偏移跟踪发送检查点的频率。两个属性的默认值都是 60 秒。您还可以使用 refresh.groups.interval.seconds 属性更改检查新消费者组的频率,该属性默认每 10 分钟执行一次。

由于同步是基于时间的,因此用户切换到被动集群的任何切换都可能会导致某些重复消息。

注意

如果您使用 Java 编写了应用程序,您可以使用 RemoteClusterUtils.java 实用程序通过应用程序同步偏移。实用程序从 checkpoints 主题获取消费者组的远程偏移。

9.2.3. 决定何时使用心跳连接器

heartbeat 连接器会发出心跳来检查源和目标 Kafka 集群之间的连接。内部 心跳 主题从源集群复制,这意味着心跳连接器必须连接到源集群。heartbeat 主题位于目标集群上,它允许执行以下操作:

  • 识别从中镜像数据的所有源集群
  • 验证镜像过程的存活度和延迟

这有助于确保进程因为任何原因没有卡住或已停止。虽然心跳连接器可以是监控 Kafka 集群间镜像进程的宝贵工具,但它并不总是需要使用它。例如,如果您的部署具有低网络延迟或少量主题,您可能希望使用日志消息或其他监控工具监控镜像过程。如果您决定不使用 heartbeat 连接器,只需从 MirrorMaker 2 配置中省略它。

9.2.4. 对齐 MirrorMaker 2 连接器的配置

为确保 MirrorMaker 2 连接器正常工作,请确保在连接器之间保持一致某些配置设置。具体来说,请确保以下属性在所有适用的连接器中具有相同的值:

  • replication.policy.class
  • replication.policy.separator
  • offset-syncs.topic.location
  • topic.filter.class

例如,source、检查点和 heartbeat 连接器的 replication.policy.class 的值必须相同。不匹配或缺失的设置会导致数据复制或偏移同步出现问题,因此必须使用同一设置保持所有相关连接器配置。

9.3. 连接器制作者和消费者配置

MirrorMaker 2 连接器使用内部制作者和消费者。如果需要,您可以配置这些制作者和消费者来覆盖默认设置。

重要

生产者和消费者配置选项取决于 MirrorMaker 2 的实施,可能随时更改。

生产者和消费者配置适用于所有连接器。您在 config/connect-mirror-maker.properties 文件中指定配置。

使用属性文件以以下格式覆盖制作者和消费者的任何默认配置:

  • <source_cluster_name>.consumer.<property>
  • <source_cluster_name>.producer.<property>
  • <target_cluster_name>.consumer.<property>
  • <target_cluster_name>.producer.<property>

以下示例演示了如何配置制作者和消费者。尽管为所有连接器设置了属性,但有些配置属性仅与某些连接器相关。

连接器制作者和消费者配置示例

clusters=cluster-1,cluster-2

# ...
cluster-1.consumer.fetch.max.bytes=52428800
cluster-2.producer.batch.size=327680
cluster-2.producer.linger.ms=100
cluster-2.producer.request.timeout.ms=30000

9.4. 指定最大任务数

连接器创建负责移动 Kafka 中的数据的任务。每个连接器由一个或多个任务组成,它们分布到运行这些任务的一组 worker pod 中。在复制大量分区或同步大量消费者组的偏移时,增加任务数量可以帮助解决性能问题。

任务并行运行。为 worker 分配一个或多个任务。单个任务由一个 worker pod 处理,因此您不需要比任务更多的 worker pod。如果有多个任务,worker 会处理多个任务。

您可以使用 tasks.max 属性在 MirrorMaker 配置中指定最大连接器任务数量。如果没有指定最多任务数量,默认设置是一个任务。

heartbeat 连接器始终使用单个任务。

为源和检查点连接器启动的任务数量是可能任务的最大数量和 tasks.max 的值之间的较低值。对于源连接器,可能的最大任务数量是从源集群复制的每个分区。对于检查点连接器,可能的最大任务数都是从源集群复制的每个消费者组。在设置最多任务数量时,请考虑分区数量和支持进程的硬件资源。

如果基础架构支持处理开销,增加任务数量可以提高吞吐量和延迟。例如,添加更多任务可减少当有大量分区或消费者组时轮询源集群所需的时间。

MirrorMaker 连接器的 tasks.max 配置

clusters=cluster-1,cluster-2
# ...
tasks.max = 10

默认情况下,M MirrorMaker 2 每 10 分钟检查新的消费者组。您可以调整 refresh.groups.interval.seconds 配置以更改频率。在调整较低时要小心。更频繁的检查可能会对性能造成负面影响。

9.5. ACL 规则同步

如果使用 AclAuthorizer,管理对代理访问的 ACL 规则也适用于远程主题。读取源主题的用户可以读取其远程的等效内容。

注意

OAuth 2.0 授权不支持以这种方式访问远程主题。

9.6. 以专用模式运行 MirrorMaker 2

使用 MirrorMaker 2 通过配置在 Kafka 集群间同步数据。此流程演示了如何配置和运行专用的单节点 MirrorMaker 2 集群。专用集群使用 Kafka Connect worker 节点在 Kafka 集群间镜像数据。目前,专用模式的 MirrorMaker 2 仅适用于单个 worker 节点。

注意

也可以以分布式模式运行 MirrorMaker 2。在分布式模式下,M MirrorMaker 2 作为连接器在 Kafka Connect 集群中运行。Kafka 为数据复制提供 MirrorMaker 源连接器。如果要使用连接器而不是运行专用 MirrorMaker 集群,则必须在 Kafka Connect 集群中配置连接器。如需更多信息,请参阅 Apache Kafka 文档

以前版本的 MirrorMaker 继续支持,方法是在 传统模式下运行 MirrorMaker 2

配置必须指定:

  • 每个 Kafka 集群
  • 每个集群的连接信息,包括 TLS 身份验证
  • 复制流和方向

    • 集群到集群
    • 主题主题
  • 复制规则
  • 提交偏移跟踪间隔

此流程描述了如何通过在属性文件中创建配置来实现 MirrorMaker 2,然后在使用 MirrorMaker 脚本文件设置连接时传递属性。

您可以指定您要从源集群复制的主题和消费者组。您可以指定源和目标集群的名称,然后指定要复制的主题和消费者组。

在以下示例中,为从集群 1 复制到 2 的指定主题和消费者组。

复制特定主题和消费者组的配置示例

clusters=cluster-1,cluster-2
cluster-1->cluster-2.topics = topic-1, topic-2
cluster-1->cluster-2.groups = group-1, group-2

您可以提供名称列表或使用正则表达式。默认情况下,如果没有设置这些属性,则会复制所有主题和消费者组。您还可以使用 Evolution 作为正则表达式来复制所有主题和消费者组。 但是,尝试只指定您需要指定主题和消费者组,以避免在集群中造成不必要的额外负载。

开始前

./config/connect-mirror-maker.properties 中提供了示例配置属性文件。

先决条件

  • 您需要在您复制的每个 Kafka 集群节点的主机中安装 AMQ Streams。

流程

  1. 在文本编辑器中打开示例属性文件,或创建一个新文件,并编辑该文件使其包含连接信息以及每个 Kafka 集群的复制流程。

    以下示例显示了连接两个集群( cluster-1cluster -2)的配置。集群名称可以通过 clusters 属性进行配置。

    MirrorMaker 2 配置示例

    clusters=cluster-1,cluster-2 1
    
    cluster-1.bootstrap.servers=<cluster_name>-kafka-bootstrap-<project_name_one>:443 2
    cluster-1.security.protocol=SSL 3
    cluster-1.ssl.truststore.password=<truststore_name>
    cluster-1.ssl.truststore.location=<path_to_truststore>/truststore.cluster-1.jks_
    cluster-1.ssl.keystore.password=<keystore_name>
    cluster-1.ssl.keystore.location=<path_to_keystore>/user.cluster-1.p12
    
    cluster-2.bootstrap.servers=<cluster_name>-kafka-bootstrap-<project_name_two>:443 4
    cluster-2.security.protocol=SSL 5
    cluster-2.ssl.truststore.password=<truststore_name>
    cluster-2.ssl.truststore.location=<path_to_truststore>/truststore.cluster-2.jks_
    cluster-2.ssl.keystore.password=<keystore_name>
    cluster-2.ssl.keystore.location=<path_to_keystore>/user.cluster-2.p12
    
    cluster-1->cluster-2.enabled=true 6
    cluster-2->cluster-1.enabled=true 7
    cluster-1->cluster-2.topics=.* 8
    cluster-2->cluster-1.topics=topic-1, topic-2 9
    cluster-1->cluster-2.groups=.* 10
    cluster-2->cluster-1.groups=group-1, group-2 11
    
    replication.policy.separator=- 12
    sync.topic.acls.enabled=false 13
    refresh.topics.interval.seconds=60 14
    refresh.groups.interval.seconds=60 15

    1
    每个 Kafka 集群都使用其别名来标识。
    2
    cluster-1 的连接信息,使用 bootstrap 地址和端口 443。两个集群都使用端口 443 连接到使用 OpenShift Routes 的 Kafka。
    3
    ssl. 属性定义 cluster-1 的 TLS 配置。
    4
    cluster-2 的连接信息。
    5
    ssl. 属性定义 cluster-2 的 TLS 配置。
    6
    cluster-1cluster-2 启用复制流程。
    7
    cluster-2cluster-1 启用复制流程。
    8
    将所有主题从 cluster-1 复制到 cluster-2。源连接器复制指定的主题。checkpoint 连接器跟踪指定主题的偏移量。
    9
    将特定主题从 cluster-2 复制到 cluster-1
    10
    将所有消费者组从 cluster-1 复制到 cluster-2。checkpoint 连接器复制指定的消费者组。
    11
    将特定消费者组从 cluster-2 复制到 cluster-1
    12
    定义用于重命名远程主题的分隔符。
    13
    启用后,ACL 将应用到同步的主题。默认值为 false
    14
    检查要同步的新主题之间的周期。
    15
    检查要同步的新消费者组之间的周期。
  2. OPTION:如果需要,添加一个策略来覆盖远程主题的自动重命名。该主题不会用源集群的名称来附加名称,而是保留其原始名称。

    此可选设置用于主动/被动备份和数据迁移。

    replication.policy.class=org.apache.kafka.connect.mirror.IdentityReplicationPolicy
  3. OPTION :如果要同步消费者组偏移,请添加配置来启用和管理同步:

    refresh.groups.interval.seconds=60
    sync.group.offsets.enabled=true 1
    sync.group.offsets.interval.seconds=60 2
    emit.checkpoints.interval.seconds=60 3
    1
    用于同步消费者组偏移的可选设置,这对于在主动/被动配置中恢复非常有用。默认情况下不启用同步。
    2
    如果启用了使用者组偏移的同步,您可以调整同步的频率。
    3
    调整检查偏移跟踪的频率。如果您更改了偏移同步的频率,您可能需要调整这些检查的频率。
  4. 在目标集群中启动 ZooKeeper 和 Kafka:

    su - kafka
    /opt/kafka/bin/zookeeper-server-start.sh -daemon \
    /opt/kafka/config/zookeeper.properties
    /opt/kafka/bin/kafka-server-start.sh -daemon \
    /opt/kafka/config/server.properties
  5. 使用您在属性文件中定义的集群连接配置和复制策略启动 MirrorMaker:

    /opt/kafka/bin/connect-mirror-maker.sh \
    /opt/kafka/config/connect-mirror-maker.properties

    MirrorMaker 在集群之间建立连接。

  6. 对于每个目标集群,验证主题是否复制:

    /opt/kafka/bin/kafka-topics.sh --bootstrap-server <broker_address> --list

9.7. 在旧模式中使用 MirrorMaker 2

这个步骤描述了如何将 MirrorMaker 2 配置为在旧模式中使用它。旧模式支持早期版本的 MirrorMaker。

MirrorMaker 脚本 /opt/kafka/bin/kafka-mirror-maker.sh 可以在传统模式下运行 MirrorMaker 2。

重要

Kafka MirrorMaker 1 (称为文档中的 MirrorMaker )已在 Apache Kafka 3.0.0 中弃用,并将在 Apache Kafka 4.0.0 中删除。因此,Kafka MirrorMaker 1 也已在 AMQ Streams 中弃用。当我们采用 Apache Kafka 4.0.0 时,Kafka MirrorMaker 1 将从 AMQ Streams 中删除。作为替换,将 MirrorMaker 2 与 IdentityReplicationPolicy 搭配使用。

先决条件

您需要当前与旧版本的 MirrorMaker 搭配使用的属性文件。

  • /opt/kafka/config/consumer.properties
  • /opt/kafka/config/producer.properties

流程

  1. 编辑 MirrorMaker consumer.propertiesproducer.properties 文件,以关闭 MirrorMaker 2 的功能。

    例如:

    replication.policy.class=org.apache.kafka.mirror.LegacyReplicationPolicy 1
    
    refresh.topics.enabled=false 2
    refresh.groups.enabled=false
    emit.checkpoints.enabled=false
    emit.heartbeats.enabled=false
    sync.topic.configs.enabled=false
    sync.topic.acls.enabled=false
    1
    模拟以前的 MirrorMaker 版本。
    2
    MirrorMaker 2 功能被禁用,包括内部 检查点心跳 主题
  2. 保存更改,并使用您之前版本的 MirrorMaker 所使用的属性文件重启 MirrorMaker:

    su - kafka /opt/kafka/bin/kafka-mirror-maker.sh \
    --consumer.config /opt/kafka/config/consumer.properties \
    --producer.config /opt/kafka/config/producer.properties \
    --num.streams=2

    consumer 属性提供源集群和 producer 属性的配置,提供目标集群配置。

    MirrorMaker 在集群之间建立连接。

  3. 在目标集群中启动 ZooKeeper 和 Kafka:

    su - kafka
    /opt/kafka/bin/zookeeper-server-start.sh -daemon /opt/kafka/config/zookeeper.properties
    su - kafka
    /opt/kafka/bin/kafka-server-start.sh -daemon /opt/kafka/config/server.properties
  4. 对于目标集群,验证主题是否复制:

    /opt/kafka/bin/kafka-topics.sh --bootstrap-server <broker_address> --list

第 10 章 为 Kafka 组件配置日志记录

在配置属性中直接配置 Kafka 组件的日志记录级别。您还可以为 Kafka 代理、Kafka Connect 和 MirrorMaker 2 动态更改代理级别。

增加日志级别详情,如从 INFO 到 DEBUG,有助于对 Kafka 集群进行故障排除。但是,更详细的日志也可能对性能造成负面影响,并更难以诊断问题。

10.1. 配置 Kafka 日志记录属性

Kafka 组件使用 Log4j 框架进行错误日志记录。默认情况下,日志配置从 classpath 或 config 目录中读取,使用以下属性文件:

  • log4j.properties 用于 Kafka 和 ZooKeeper
  • 用于 Kafka Connect 和 MirrorMaker 2 的 connect-log4j.properties

如果没有显式设置,则日志记录器会继承每个文件中的 log4j.rootLogger 日志级别配置。您可以更改这些文件中的日志级别。您还可以为其他日志记录器添加和设置日志记录级别。

您可以使用 KAFKA_LOG4J_OPTS 环境变量更改日志属性文件的位置和名称,该变量供组件的启动脚本使用。

传递 Kafka 代理使用的日志属性文件的名称和位置

su - kafka
export KAFKA_LOG4J_OPTS="-Dlog4j.configuration=file:/my/path/to/log4j.properties"; \
/opt/kafka/bin/kafka-server-start.sh \
/opt/kafka/config/server.properties

传递 ZooKeeper 使用的日志属性文件的名称和位置

su - kafka
export KAFKA_LOG4J_OPTS="-Dlog4j.configuration=file:/my/path/to/log4j.properties"; \
/opt/kafka/bin/zookeeper-server-start.sh -daemon \
/opt/kafka/config/zookeeper.properties

传递 Kafka Connect 使用的日志属性文件的名称和位置

su - kafka
export KAFKA_LOG4J_OPTS="-Dlog4j.configuration=file:/my/path/to/connect-log4j.properties"; \
/opt/kafka/bin/connect-distributed.sh \
/opt/kafka/config/connect-distributed.properties

传递 MirrorMaker 2 使用的日志属性文件的名称和位置

su - kafka
export KAFKA_LOG4J_OPTS="-Dlog4j.configuration=file:/my/path/to/connect-log4j.properties"; \
/opt/kafka/bin/connect-mirror-maker.sh \
/opt/kafka/config/connect-mirror-maker.properties

10.2. 为 Kafka 代理日志记录器动态更改日志记录级别

Kafka 代理日志记录由每个代理的代理日志记录器提供。在运行时动态更改代理日志记录器的日志级别,而无需重启代理。

您还可以动态地将代理日志记录器重置为其默认日志记录级别。

流程

  1. 切换到 kafka 用户:

    su - kafka
  2. 使用 kafka-configs.sh 工具列出代理的所有代理日志记录器:

    /opt/kafka/bin/kafka-configs.sh --bootstrap-server <broker_address> --describe --entity-type broker-loggers --entity-name BROKER-ID

    例如,对于代理 0

    /opt/kafka/bin/kafka-configs.sh --bootstrap-server localhost:9092 --describe --entity-type broker-loggers --entity-name 0

    这会返回每个日志记录器的日志记录级别:TRACE, DEBUG, INFO, WARN, ERROR, 或 FATAL

    例如:

    #...
    kafka.controller.ControllerChannelManager=INFO sensitive=false synonyms={}
    kafka.log.TimeIndex=INFO sensitive=false synonyms={}
  3. 更改一个或多个代理日志记录器的日志记录级别。使用 --alter--add-config 选项,并将每个日志记录器及其级别指定为双引号中的逗号分隔列表。

    /opt/kafka/bin/kafka-configs.sh --bootstrap-server <broker_address> --alter --add-config "LOGGER-ONE=NEW-LEVEL,LOGGER-TWO=NEW-LEVEL" --entity-type broker-loggers --entity-name BROKER-ID

    例如,对于代理 0

    /opt/kafka/bin/kafka-configs.sh --bootstrap-server localhost:9092 --alter --add-config "kafka.controller.ControllerChannelManager=WARN,kafka.log.TimeIndex=WARN" --entity-type broker-loggers --entity-name 0

    如果成功返回:

    Completed updating config for broker: 0.

重置代理日志记录器

您可以使用 kafka-configs.sh 工具将一个或多个代理日志记录器重置为其默认日志级别。使用 --alter--delete-config 选项,并使用双引号将每个代理日志记录器指定为用逗号分开的列表:

/opt/kafka/bin/kafka-configs.sh --bootstrap-server localhost:9092 --alter --delete-config "LOGGER-ONE,LOGGER-TWO" --entity-type broker-loggers --entity-name BROKER-ID

其他资源

  • Apache Kafka 文档中的 更新 代理配置

10.3. 为 Kafka Connect 和 MirrorMaker 2 动态更改日志记录级别

在运行时动态更改 Kafka Connect worker 或 MirrorMaker 2 连接器的日志级别,而无需重启。

使用 Kafka Connect API 临时更改 worker 或连接器日志记录器的日志级别。Kafka Connect API 提供了一个 admin/loggers 端点来获取或修改日志记录级别。使用 API 更改日志级别时,connect-log4j.properties 配置文件中的日志记录器配置不会改变。如果需要,您可以永久更改配置文件中的日志级别。

注意

您只能在分布式或独立模式运行时更改 MirrorMaker 2 的日志级别。专用 MirrorMaker 2 集群没有 Kafka Connect REST API,因此无法更改日志级别。

Kafka Connect API 的默认监听程序位于端口 8083 上,在此过程中使用。您可以使用 admin.listeners 配置更改或添加更多监听程序,并启用 TLS 身份验证。

admin 端点的监听程序配置示例

admin.listeners=https://localhost:8083
admin.listeners.https.ssl.truststore.location=/path/to/truststore.jks
admin.listeners.https.ssl.truststore.password=123456
admin.listeners.https.ssl.keystore.location=/path/to/keystore.jks
admin.listeners.https.ssl.keystore.password=123456

如果您不希望 admin 端点可用,您可以通过指定一个空字符串来禁用它。

禁用 admin 端点的监听程序配置示例

admin.listeners=

先决条件

流程

  1. 切换到 kafka 用户:

    su - kafka
  2. 检查 connect-log4j.properties 文件中配置的日志记录器的当前日志记录级别:

    $ cat /opt/kafka/config/connect-log4j.properties
    
    # ...
    log4j.rootLogger=INFO, stdout, connectAppender
    # ...
    log4j.logger.org.apache.zookeeper=ERROR
    log4j.logger.org.reflections=ERROR

    使用 curl 命令从 Kafka Connect API 的 admin/loggers 端点检查日志级别:

    curl -s http://localhost:8083/admin/loggers/ | jq
    
    {
      "org.apache.zookeeper": {
        "level": "ERROR"
      },
      "org.reflections": {
        "level": "ERROR"
      },
      "root": {
        "level": "INFO"
      }
    }

    jq 以 JSON 格式输出。该列表显示了标准 机构根级别 日志记录器,以及具有修改日志级别的任何特定日志记录器。

    如果您在 Kafka Connect 中为 admin.listeners 配置配置 TLS (Transport Layer Security)身份验证,则日志记录器端点的地址是 admin.listeners 指定的值,其协议为 https,如 https://localhost:8083

    您还可以获取特定日志记录器的日志级别:

    curl -s http://localhost:8083/admin/loggers/org.apache.kafka.connect.mirror.MirrorCheckpointConnector | jq
    
    {
      "level": "INFO"
    }
  3. 使用 PUT 方法更改日志记录器的日志级别:

    curl -Ss -X PUT -H 'Content-Type: application/json' -d '{"level": "TRACE"}' http://localhost:8083/admin/loggers/root
    
    {
      # ...
    
      "org.reflections": {
        "level": "TRACE"
      },
      "org.reflections.Reflections": {
        "level": "TRACE"
      },
      "root": {
        "level": "TRACE"
      }
    }

    如果您更改了 root 日志程序,则默认使用了 root 日志级别的日志程序的日志级别也会被改变。

第 11 章 处理大量信息

如果您的 AMQ Streams 部署需要处理大量信息,您可以使用配置选项来优化吞吐量和延迟。

Kafka 生成者和消费者配置可帮助控制对 Kafka 代理的请求大小和频率。有关配置选项的更多信息,请参阅以下内容:

您还可以将相同的配置选项与 Kafka Connect 运行时源连接器(包括 MirrorMaker 2)和接收器连接器使用的制作者和消费者一起使用。

源连接器
  • Kafka Connect 运行时的制作者会向 Kafka 集群发送信息。
  • 对于 MirrorMaker 2,因为源系统是 Kafka,消费者从源 Kafka 集群检索信息。
sink 连接器
  • Kafka Connect 运行时的用户从 Kafka 集群检索信息。

对于消费者配置(consumer.*),您可以增加在单个获取请求中获取的数据量,以减少延迟。您可以使用 fetch.max.bytesmax.partition.fetch.bytes 属性增加 fetch 请求大小。您还可以使用 max.poll.records 属性设置从消费者缓冲区返回的消息数的最大限制。

对于生成者配置(生成者),您可以增加在单个生成请求中发送的消息批处理的大小。您可以使用 batch.size 属性增加批处理大小。更大的批处理大小可减少准备好发送的未完成消息的数量以及消息队列中的 backlog 的大小。发送到同一分区的消息会并行批处理。当达到批处理大小时,将生成请求发送到目标集群。通过增加批处理大小,生成请求会延迟,并将更多消息添加到批处理中,并同时发送到代理。当您只有处理大量消息的几个主题分区时,这可以提高吞吐量。

考虑制作者为合适的生产批处理大小处理的记录的数量和大小。

使用 linger.ms 添加等待时间(毫秒)以在生成者负载减少时延迟生成请求。延迟意味着,如果记录在最大批处理大小下,可以添加更多记录到批处理中。

对于 Kafka Connect 源连接器,到目标 Kafka 集群的数据流管道如下:

Kafka Connect 源连接器的数据流管道

External data source →(Kafka Connect tasks) source message queue → producer buffer → target Kafka topic

对于 Kafka Connect sink 连接器,到目标外部数据源的数据流管道如下:

Kafka Connect sink 连接器的数据流管道

source Kafka topic → (Kafka Connect tasks) sink message queue → consumer buffer → external data source

对于 MirrorMaker 2,目标 Kafka 集群的数据镜像管道如下:

MirrorMaker 2 的数据镜像管道

source Kafka topic → (Kafka Connect tasks) source message queue → producer buffer → target Kafka topic

制作者在其缓冲区中向目标 Kafka 集群中的主题发送信息。当发生这种情况时,Kafka Connect 任务将继续轮询数据源,以将信息添加到源消息队列中。

源连接器的制作者缓冲区的大小是使用 buffer.memory 属性设置的。在缓冲区被清除前,任务会等待指定的超时周期(offset.flush.timeout.ms)。这应该有足够的时间,以便代理和偏移数据提交的信息可以确认发送消息。除关闭期间,源任务不会等待制作者为空消息队列,然后再提交偏移。

如果生成者无法满足源消息队列中消息的吞吐量,则缓冲区会被阻断,直到缓冲区内由 max.block.ms 绑定的时间周期内可用。在此期间,缓冲区中仍然发送任何未确认的信息。在确认和清除这些消息之前,新消息不会添加到缓冲区中。

您可以尝试以下配置更改,将未完成的消息的底层源消息队列保持在 manageable 大小下:

  • offset.flush.timeout.ms为单位增加默认值
  • 确保有足够的 CPU 和内存资源
  • 通过执行以下操作增加并行运行的任务数量:

    • 使用 tasks.max 属性增加并行运行的任务数量
    • 为运行任务的 worker 增加节点数量

根据可用的 CPU 和内存资源和 worker 节点数量,请考虑可以并行运行的任务数量。您可能需要继续调整配置值,直到它们具有所需的效果。

11.1. 为高容量信息配置 Kafka 连接

Kafka Connect 从源外部数据系统获取数据,并将其传递给 Kafka Connect 运行时制作者,使其复制到目标集群。

以下示例显示了 Kafka Connect 源连接器的配置。

处理大量信息的源连接器配置示例

# ...
producer.batch.size=327680
producer.linger.ms=100
# ...
tasks.max = 2

为接收器连接器添加消费者配置。

处理大量消息的接收器连接器配置示例

# ...
consumer.fetch.max.bytes=52428800
consumer.max.partition.fetch.bytes=1048576
consumer.max.poll.records=500
# ...
tasks.max = 2

11.2. 为高卷消息配置 MirrorMaker 2

MirrorMaker 2 从源集群获取数据,并将其传递给 Kafka Connect 运行时制作者,以便将其复制到目标集群。

以下示例显示了 MirrorMaker 2 的配置。配置与从来源获取消息的消费者相关,以及向目标 Kafka 集群发送消息的制作者。

用于处理大量消息的 MirrorMaker 2 配置示例

clusters=cluster-1,cluster-2
# ...
cluster-2.producer.batch.size=327680
cluster-2.producer.linger.ms=100
cluster-1.consumer.fetch.max.bytes=52428800
cluster-1.consumer.max.partition.fetch.bytes=1048576
cluster-1.consumer.max.poll.records=500
# ...
tasks.max = 2

第 12 章 使用 Kafka 静态配额插件设置代理限制

重要

Kafka 静态配额插件只是技术预览。技术预览功能不被红帽产品服务级别协议(SLA)支持,且可能无法完成。红帽不推荐在生产环境中实施任何技术预览功能。此技术预览功能为您提供对即将推出的产品创新的早期访问,允许您在开发过程中测试并提供反馈。有关红帽技术预览功能支持范围的更多信息,请参阅技术预览功能支持范围

使用 Kafka 静态配额插件在 Kafka 集群中的代理上设置吞吐量和存储限制。您可以通过在 Kafka 配置文件中添加属性来启用插件和设置限制。您可以设置字节阈值和存储配额,以在与代理交互的客户端上放置限制。

您可以为制作者和消费者带宽设置字节阈值。总限制在访问代理的所有客户端间分布。例如,您可以为制作者设置字节阈值 40 MBps。如果两个制作者正在运行,它们各自限制为 20 MBps 的吞吐量。

存储配额在软限制和硬限制之间节流 Kafka 磁盘存储限制。限制适用于所有可用磁盘空间。生产者在软限制和硬限制之间逐渐慢。限制可防止磁盘填满速度超过其容量。完整磁盘可能会导致难以重新处理的问题。硬限制是最大存储限制。

注意

对于 JBOD 存储,限制适用于所有磁盘。如果代理使用两个 1 TB 磁盘,并且配额为 1.1 TB,则一个磁盘可能会填满,另一个磁盘将几乎为空。

先决条件

  • AMQ Streams 安装 在所有将用作 Kafka 代理的主机上。
  • 一个 ZooKeeper 集群已被配置并运行

流程

  1. 编辑 /opt/kafka/config/server.properties Kafka 配置文件。

    此示例配置中显示了插件属性。

    Kafka 静态配额插件配置示例

    # ...
    client.quota.callback.class=io.strimzi.kafka.quotas.StaticQuotaCallback 1
    client.quota.callback.static.produce=1000000 2
    client.quota.callback.static.fetch=1000000 3
    client.quota.callback.static.storage.soft=400000000000 4
    client.quota.callback.static.storage.hard=500000000000 5
    client.quota.callback.static.storage.check-interval=5 6
    # ...

    1
    加载 Kafka Static Quota 插件。
    2
    设置制作者字节阈值。本示例中为 1 Mbps.
    3
    设置消费者字节阈值。本示例中为 1 Mbps.
    4
    为存储设置较低软限制。在本示例中为 400 GB。
    5
    为存储设置更高的硬限制。本例中为 500 GB。
    6
    设置存储检查间隔(以秒为单位)。本例中有 5 秒。您可以将其设置为 0 来禁用检查。
  2. 使用默认配置文件启动 Kafka 代理。

    su - kafka
    /opt/kafka/bin/kafka-server-start.sh -daemon /opt/kafka/config/server.properties
  3. 验证 Kafka 代理是否正在运行。

    jcmd | grep Kafka

第 13 章 添加和删除 Kafka 代理和 ZooKeeper 节点

在 Kafka 集群中,管理代理和删除代理和 ZooKeeper 节点对于维护稳定且可扩展的系统至关重要。当您添加到可用代理数量时,您可以为代理中的主题配置默认复制因素和最小同步副本。您可以使用动态重新配置在不中断的情况下从 ensemble 中添加和删除 ZooKeeper 节点。

13.1. 通过添加或删除代理来扩展集群

通过添加代理扩展 Kafka 集群可以提高集群的性能和可靠性。添加更多代理会增加可用资源,允许集群处理较大的工作负载并处理更多信息。它还可以通过提供更多副本和备份来提高容错。相反,删除使用率不足的代理可以降低资源消耗并提高效率。必须仔细进行缩放以避免中断或数据丢失。通过在集群中的所有代理间重新分发分区,每个代理的资源利用率会减少,这可以提高集群的整体吞吐量。

注意

要增加 Kafka 主题的吞吐量,您可以增加该主题的分区数量。这允许加载集群中的不同代理之间共享该主题。但是,如果每个代理都受特定资源(如 I/O)的限制,添加更多分区不会增加吞吐量。在这种情况下,您需要在集群中添加更多代理。

在运行多节点 Kafka 集群时添加代理会影响作为副本的集群中的代理数量。主题的实际复制因素由 default.replication.factormin.insync.replicas 的设置以及可用代理的数量决定。例如,复制因素 3 表示主题的每个分区在三个代理之间复制,确保在代理失败时进行容错。

副本配置示例

default.replication.factor = 3
min.insync.replicas = 2

当您添加或删除代理时,Kafka 不会自动重新分配分区。执行此操作的最佳方法是使用 Cruise Control。您可以在扩展集群或缩减时使用 Cruise Control 的 add-brokersremove-brokers 模式。

  • 在扩展 Kafka 集群后,使用 add-brokers 模式,将分区副本从现有代理移到新添加的代理中。
  • 在缩减 Kafka 集群前,使用 remove-brokers 模式,将分区副本从要删除的代理移出。
注意

在缩减代理时,您无法指定要从集群中移除的特定 pod。相反,代理移除过程从最高编号的 pod 开始。

13.2. 将节点添加到 ZooKeeper 集群

在不停止整个集群的情况下,使用动态重新配置 从 ZooKeeper 集群添加节点。动态重新配置允许 ZooKeeper 在不中断的情况下更改组成 ZooKeeper 集群的一组节点的成员资格。

先决条件

  • ZooKeeper 配置文件中启用了动态重新配置(reconfigEnabled=true)。
  • 启用了 ZooKeeper 身份验证,您可以使用身份验证机制访问新的服务器。

流程

对您要添加的每个 ZooKeeper 服务器执行以下步骤:

  1. 在 ZooKeeper 集群中添加服务器,如 第 4.1 节 “运行多节点 ZooKeeper 集群” 所述,然后启动 ZooKeeper。
  2. 请注意新的服务器的 IP 地址并配置了访问端口。
  3. 为服务器启动 zookeeper-shell 会话。从可访问集群的机器运行以下命令(如果可以访问集群,这可能是一个 ZooKeeper 节点或本地机器)。

    su - kafka
    /opt/kafka/bin/zookeeper-shell.sh <ip-address>:<zk-port>
  4. 在 shell 会话中,运行 ZooKeeper 节点时,输入以下行将新的服务器作为投票成员添加到仲裁中:

    reconfig -add server.<positive-id> = <address1>:<port1>:<port2>[:role];[<client-port-address>:]<client-port>

    例如:

    reconfig -add server.4=172.17.0.4:2888:3888:participant;172.17.0.4:2181

    其中 <positive-id> 是新服务器 ID 4

    对于两个端口,<port1> 2888 用于 ZooKeeper 服务器之间的通信,<port2> 3888 用于领导选举机制。

    新配置传播到 ZooKeeper 集群中的其他服务器,现在新的服务器现在是仲裁的完整成员。

13.3. 从 ZooKeeper 集群中删除节点

在不停止整个集群的情况下,使用动态重新配置 从 ZooKeeper 集群中删除节点。动态重新配置允许 ZooKeeper 在不中断的情况下更改组成 ZooKeeper 集群的一组节点的成员资格。

先决条件

  • ZooKeeper 配置文件中启用了动态重新配置(reconfigEnabled=true)。
  • 启用了 ZooKeeper 身份验证,您可以使用身份验证机制访问新的服务器。

流程

为每个删除的 ZooKeeper 服务器执行以下步骤:

  1. 登录到在缩减后会保留的其中一个服务器上的 zookeeper-shell(例如,服务器 1)。

    注意

    使用为 ZooKeeper 集群配置的验证机制访问服务器。

  2. 删除服务器,如 server 5。

    reconfig -remove 5
  3. 取消激活您删除的服务器。

第 14 章 使用 Cruise Control 进行集群重新平衡

Cruise Control 是一个用于自动化 Kafka 操作的开源系统,如监控集群工作负载、根据预定义的限制重新平衡集群,并检测和修复异常情况。它由四个主要组件组成,即 Load Monitor、Anomaly Detector 和 Executor-​,以及用于客户端交互的 REST API。

您可以使用 Cruise Control 来重新平衡 Kafka 集群。Red Hat Enterprise Linux 上的 AMQ Streams 的 Cruise Control 作为单独的 zipped 发行版本提供。

AMQ Streams 使用 REST API 来支持以下 Cruise Control 功能:

  • 从优化目标生成优化建议。
  • 根据优化提议,重新平衡 Kafka 集群。

    优化目标

    优化目标描述了从重新平衡实现的特定目标。例如,目标是更加均匀地在代理间分发主题副本。您可以更改要通过配置包含哪些目标。目标定义为一个硬目标或软目标。您可以通过 Cruise Control 部署配置添加硬目标。您还有特定于这些类别的主要、默认和用户提供的目标。

    • 目标是预先设置的,必须满足优化建议才能成功。
    • 不需要满足软 目标 才能成功进行优化建议。如果达到所有硬目标,则可以设置它们。
    • 主要目标从 Cruise Control 中继承。有些是预先设置为硬目标。默认情况下,主目标用于优化提议。
    • 默认目标 与主要目标相同。您可以指定您自己的一组默认目标。
    • 用户提供的目标是配置用于生成特定优化器的默认目标子集。
    优化提议

    优化建议由您要从重新平衡实现的目标组成。您可以生成一个优化建议,以创建提议的更改概述以及重新平衡的结果。目标按照特定优先级顺序进行评估。然后您可以选择批准或拒绝提议。您可以拒绝使用调整的目标集合再次运行它。

    您可以通过向以下 API 端点之一发出请求并批准优化建议。

    • /rebalance 端点用于运行一个完整的重新平衡操作。
    • /add_broker 端点在扩展 Kafka 集群时添加代理以重新平衡。
    • 在缩减 Kafka 集群时,在删除代理前,要重新平衡的 /remove_broker 端点。

您可以通过配置属性文件配置优化目标。AMQ Streams 为 Cruise Control 提供示例属性文件。

目前还不支持其他 Cruise Control 功能,包括自我修复、通知、编写目标以及更改主题复制因素。

14.1. Cruise Control 组件和功能

Cruise Control 包括四个主要组件 - Load Monitor、Anomaly Detector 和 Executor-​ 以及用于客户端交互的 REST API。AMQ Streams 使用 REST API 来支持以下 Cruise Control 功能:

  • 从优化目标生成优化建议。
  • 根据优化提议,重新平衡 Kafka 集群。
优化目标

优化目标描述了从重新平衡实现的特定目标。例如,目标是更加均匀地在代理间分发主题副本。您可以更改要通过配置包含哪些目标。目标定义为一个硬目标或软目标。您可以通过 Cruise Control 部署配置添加硬目标。您还有特定于这些类别的主要、默认和用户提供的目标。

  • 目标是预先设置的,必须满足优化建议才能成功。
  • 不需要满足软 目标 才能成功进行优化建议。如果达到所有硬目标,则可以设置它们。
  • 主要目标从 Cruise Control 中继承。有些是预先设置为硬目标。默认情况下,主目标用于优化提议。
  • 默认目标 与主要目标相同。您可以指定您自己的一组默认目标。
  • 用户提供的目标是 配置用于生成特定优化建议的默认目标子集。
优化提议

优化建议由您要从重新平衡实现的目标组成。您可以生成一个优化建议,以创建提议的更改概述以及重新平衡的结果。目标按照特定优先级顺序进行评估。然后您可以选择批准或拒绝提议。您可以拒绝使用调整的目标集合再次运行它。

您可以使用三种模式之一生成优化提议。

  • full 是默认模式,运行完全重新平衡。
  • add-brokers 是扩展 Kafka 集群时添加代理时使用的模式。
  • remove-brokers 是您在缩减 Kafka 集群时删除代理前使用的模式。

目前还不支持其他 Cruise Control 功能,包括自我修复、通知、编写目标以及更改主题复制因素。

其他资源

14.2. 下载 Cruise Control

可从红帽网站下载 Cruise Control 的 ZIP 文件发布。您可以从 AMQ Streams 软件下载页面下载 Red Hat AMQ Streams 的最新版本。

流程

  1. 从红帽客户门户下载 Red Hat AMQ Streams Cruise Control 归档的最新版本。
  2. 创建 /opt/cruise-control 目录:

    sudo mkdir /opt/cruise-control
  3. 将 Cruise Control ZIP 文件的内容提取到新目录中:

    unzip amq-streams-<version>-cruise-control-bin.zip -d /opt/cruise-control
  4. /opt/cruise-control 目录的所有权改为 kafka 用户:

    sudo chown -R kafka:kafka /opt/cruise-control

14.3. 部署 Cruise Control Metrics Reporter

在启动 Cruise Control 前,您必须将 Kafka 代理配置为使用提供的 Cruise Control Metrics Reporter。Metrics Reporter 的文件由 AMQ Streams 安装工件提供。

在运行时加载时,Metrics Reporter 会将指标发送到 __CruiseControlMetrics 主题,其中有三个自动创建的主题之一。Cruise Control 使用这些指标来创建和更新工作负载模型并计算优化建议。

先决条件

  • kafka 用户身份登录 Red Hat Enterprise Linux。
  • Kafka 和 ZooKeeper 正在运行。

流程

对于 Kafka 集群中的每个代理,一次都有一个代理:

  1. 停止 Kafka 代理:

    /opt/kafka/bin/kafka-server-stop.sh
  2. 在 Kafka 配置文件中 (/opt/kafka/config/server.properties) 配置 Cruise Control Metrics Reporter:

    1. CruiseControlMetricsReporter 类添加到 metric.reporters 配置选项。不要删除任何现有的 Metrics Reporters。

      metric.reporters=com.linkedin.kafka.cruisecontrol.metricsreporter.CruiseControlMetricsReporter
    2. 添加以下配置选项和值:

      cruise.control.metrics.topic.auto.create=true
      cruise.control.metrics.topic.num.partitions=1
      cruise.control.metrics.topic.replication.factor=1

      这些选项允许 Cruise Control Metrics Reporter 创建 __CruiseControlMetrics 主题,其日志清理策略为 DELETE。如需更多信息,请参阅 Auto-created topicsLog cleanup policy for Cruise Control Metrics topic

  3. 如果需要,配置 SSL。

    1. 在 Kafka 配置文件中(/opt/kafka/config/server.properties)通过设置相关的客户端配置属性在 Cruise Control Metrics Reporter 和 Kafka 代理之间配置 SSL。

      Metrics Reporter 接受带有 cruise.control.metrics.reporter 前缀的所有特定于标准的配置属性。例如: cruise.control.metrics.reporter.ssl.truststore.password

    2. 在 Cruise Control 属性文件中(/opt/cruise-control/config/cruisecontrol.properties)通过设置相关的客户端配置属性在 Kafka 代理和 Cruise Control 服务器之间配置 SSL。

      Cruise Control 从 Kafka 中继承 SSL 客户端属性选项,并将这些属性用于所有 Cruise Control 服务器客户端。

  4. 重启 Kafka 代理:

    /opt/kafka/bin/kafka-server-start.sh -daemon /opt/kafka/config/server.properties

    有关在多节点集群中重启代理的详情,请参考 第 4.3 节 “执行 Kafka 代理的安全滚动重启”

  5. 对剩余的代理重复步骤 1-5。

14.4. 配置并启动 Cruise Control

配置 Cruise Control 使用的属性,然后使用 kafka-cruise-control-start.sh 脚本启动 Cruise Control 服务器。服务器托管在整个 Kafka 集群的一台机器上。

Cruise Control 启动时会自动创建三个主题。如需更多信息,请参阅 自动创建的主题

先决条件

流程

  1. 编辑 Cruise Control 属性文件 (/opt/cruise-control/config/cruisecontrol.properties)。
  2. 配置以下示例配置中显示的属性:

    # The Kafka cluster to control.
    bootstrap.servers=localhost:9092 1
    
    # The replication factor of Kafka metric sample store topic
    sample.store.topic.replication.factor=2 2
    
    # The configuration for the BrokerCapacityConfigFileResolver (supports JBOD, non-JBOD, and heterogeneous CPU core capacities)
    #capacity.config.file=config/capacity.json
    #capacity.config.file=config/capacityCores.json
    capacity.config.file=config/capacityJBOD.json 3
    
    # The list of goals to optimize the Kafka cluster for with pre-computed proposals
    default.goals={List of default optimization goals} 4
    
    # The list of supported goals
    goals={list of main optimization goals} 5
    
    # The list of supported hard goals
    hard.goals={List of hard goals} 6
    
    # How often should the cached proposal be expired and recalculated if necessary
    proposal.expiration.ms=60000 7
    
    # The zookeeper connect of the Kafka cluster
    zookeeper.connect=localhost:2181 8
    1
    Kafka 代理的主机和端口号(始终为 9092)。
    2
    Kafka 指标示例存储主题的复制因素。如果要在单节点 Kafka 和 ZooKeeper 集群中评估 Cruise Control,请将此属性设置为 1。对于生产环境,请将此属性设置为 2 或更多。
    3
    为代理资源设置最大容量限制的配置文件。使用适用于 Kafka 部署配置的文件。如需更多信息,请参阅 容量配置
    4
    以逗号分隔的默认优化目标列表,使用完全限定域名(FQDN)。许多主要优化目标(请参见 5)已设为默认优化目标;如果需要,您可以添加或删除目标。更多信息请参阅 第 14.5 节 “优化目标概述”
    5
    以逗号分隔的主优化目标列表,使用 FQDN。要完全排除用于生成优化建议的目标,请从列表中删除它们。更多信息请参阅 第 14.5 节 “优化目标概述”
    6
    以逗号分隔的硬目标列表,使用 FQDN。七大优化目标已设置为硬目标;如果需要,您可以添加或删除目标。更多信息请参阅 第 14.5 节 “优化目标概述”
    7
    刷新从默认优化目标生成的缓存的优化建议的时间间隔(毫秒)。更多信息请参阅 第 14.6 节 “优化提议概述”
    8
    ZooKeeper 连接的主机和端口号(始终为 2181)。
  3. 启动 Cruise Control 服务器。默认情况下,服务器从端口 9092 开始;可选,还可指定不同的端口。

    cd /opt/cruise-control/
    ./kafka-cruise-control-start.sh config/cruisecontrol.properties <port_number>
  4. 要验证 Cruise Control 是否正在运行,请向 Cruise Control 服务器的 /state 端点发送 GET 请求:

    curl 'http://HOST:PORT/kafkacruisecontrol/state'

自动创建的主题

下表显示了在 Cruise Control 启动时自动创建的三个主题。Cruise Control 正常工作且不得删除或更改这些主题。

表 14.1. 自动创建的主题

自动创建的主题创建方功能

__CruiseControlMetrics

Cruise Control Metrics Reporter

将 Metrics Reporter 中的原始指标存储在每个 Kafka 代理中。

__KafkaCruiseControlPartitionMetricSamples

Sything Control

存储每个分区派生的指标。它们由指标示例聚合器创建。

__KafkaCruiseControlModelTrainingSamples

Sything Control

存储用于创建 Cluster Workload Model 的指标示例。

要确保在自动创建的主题中禁用日志压缩,请确保配置 Cruise Control Metrics Reporter,如 第 14.3 节 “部署 Cruise Control Metrics Reporter” 所述。日志压缩可能会删除 Cruise Control 所需的记录,并阻止它正常工作。

14.5. 优化目标概述

优化目标对 Kafka 集群的工作负载重新分配和资源利用率的限制。要重新平衡 Kafka 集群,Cruise Control 使用优化目标来 生成优化建议

14.5.1. 优先级的目标顺序

Red Hat Enterprise Linux 上的 AMQ Streams 支持在 Cruise Control 项目中开发的所有优化目标。支持的目标(以默认降序排列)如下:

  1. rack-awareness
  2. 一组主题的每个代理的最小领导副本数
  3. 副本容量
  4. 容量:磁盘容量、网络入站容量、网络出站容量
  5. CPU 容量
  6. 副本分发
  7. 潜在的网络输出
  8. 资源分布:磁盘使用分发、网络入站使用分布、网络出站使用分布
  9. 领导字节速率分布
  10. 主题副本分发
  11. CPU 用量分布
  12. 领导副本分发
  13. 首选领导选举机制
  14. Kafka Assigner 磁盘用量分布
  15. intra-broker 磁盘容量
  16. intra-broker 磁盘用量

有关每个优化目标的更多信息,请参阅 Cruise Control Wiki 中的 目标

14.5.2. Cruise Control 属性文件中的目标配置

您可以在 cruise-control/config/ 目录中的 cruisecontrol.properties 文件中设置优化目标。Cruise Control 具有必须满足的硬优化目标的配置,以及主要、默认和用户提供的优化目标。

您可以在以下配置中指定以下类型的优化目标:

  • Main goals — cruisecontrol.properties 文件
  • Hard goals — cruisecontrol.properties 文件
  • Default goals — cruisecontrol.properties 文件
  • User-provided goals — runtime 参数

另外,用户提供的 优化目标在运行时设置为对 /rebalance 端点的请求的参数。

优化目标可能会受到代理资源的任何 容量限制

14.5.3. 硬和软优化目标

硬目标是在优化建议时 必须满足 的目标。没有作为硬目标配置的目标被成为软目标。您可以将软目标视为 best effort 目标:它们不需要在优化建议方面满足,但包含在优化计算中。

Cruise Control 将计算满足所有硬目标以及尽可能多的软目标(按优先级顺序)的优化建议。满足所有硬目标的优化方法由 Analyzer 拒绝,不会向用户发送。

注意

例如,您可能有一个软目标来在集群间平均分配主题的副本(主题分布目标)。如果这样做可让所有配置的硬目标满足,则 Cruise Control 将忽略这个目标。

在 Cruise Control 中,以下 主要优化目标 被预先设置为硬目标:

RackAwareGoal; MinTopicLeadersPerBrokerGoal; ReplicaCapacityGoal; DiskCapacityGoal; NetworkInboundCapacityGoal; NetworkOutboundCapacityGoal; CpuCapacityGoal

要更改硬目标,请编辑 cruisecontrol.properties 文件的 hard.goals 属性,并使用它们的完全限定域名指定目标。

增加硬目标数量可减少 Cruise Control 将计算并生成有效的优化建议的可能性。

14.5.4. 主要优化目标

所有用户都提供了主要的优化目标。没有在主优化目标中列出的目标不适用于 Cruise Control 操作。

以下主要优化目标在 cruisecontrol.properties 文件的 goals 属性中预先设置(以降序排列):

RackAwareGoal; MinTopicLeadersPerBrokerGoal; ReplicaCapacityGoal; DiskCapacityGoal; NetworkInboundCapacityGoal; NetworkOutboundCapacityGoal; ReplicaDistributionGoal; PotentialNwOutGoal; DiskUsageDistributionGoal; NetworkInboundUsageDistributionGoal; NetworkOutboundUsageDistributionGoal; CpuUsageDistributionGoal; TopicReplicaDistributionGoal; LeaderReplicaDistributionGoal; LeaderBytesInDistributionGoal; PreferredLeaderElectionGoal

为降低复杂度,建议不要更改预先设定的主要优化目标,除非需要完全排除一个或多个目标来生成优化建议。如果需要,可以修改主优化目标的优先级顺序(如果需要),以便在默认优化目标配置中修改。

要修改预设主要优化目标,以降序在 goals 属性中指定目标列表。使用完全限定域名,如 cruisecontrol.properties 文件中所示。

您必须至少指定一个主要目标,否则 Cruise Control 将崩溃。

注意

如果更改了预先设置的主要优化目标,您必须确保配置的 hard.goals 是您配置的主要优化目标的子集。否则,生成优化建议时会发生错误。

14.5.5. 默认优化目标

Cruise Control 使用 默认优化目标 列表来生成 缓存的优化建议。更多信息请参阅 第 14.6 节 “优化提议概述”

您可以通过设置 用户提供的优化目标 来覆盖默认的优化目标

以下默认优化目标在 cruisecontrol.properties 文件的 default.goals 属性中预先设置,按优先级降序排列:

RackAwareGoal; MinTopicLeadersPerBrokerGoal; ReplicaCapacityGoal; DiskCapacityGoal; NetworkInboundCapacityGoal; NetworkOutboundCapacityGoal; CpuCapacityGoal; ReplicaDistributionGoal; PotentialNwOutGoal; DiskUsageDistributionGoal; NetworkInboundUsageDistributionGoal; NetworkOutboundUsageDistributionGoal; CpuUsageDistributionGoal; TopicReplicaDistributionGoal; LeaderReplicaDistributionGoal; LeaderBytesInDistributionGoal

您必须至少指定一个默认目标,否则 Cruise Control 将崩溃。

要修改默认优化目标,以降序在 default.goals 属性中指定目标列表。默认目标必须是主要优化目标的子集;使用完全限定域名。

14.5.6. 用户提供的优化目标

用户提供的优化目标 缩小为特定优化提议配置的默认目标。您可以根据需要设置它们,作为对 /rebalance 端点的 HTTP 请求中的参数。更多信息请参阅 第 14.9 节 “生成优化建议”

用户提供的优化目标可以为不同的场景生成优化提议。例如,您可能希望在 Kafka 集群间优化领导副本分布,而无需考虑磁盘容量或磁盘利用率。因此,您将向 /rebalance 端点发送请求,其中包含领导副本分发的单一目标。

用户提供的优化目标必须:

要在优化建议中忽略配置的硬目标,请在请求中添加 skip_hard_goals_check=true 参数。

其他资源

14.6. 优化提议概述

optimization proposal 是要生成一个更加均衡的 Kafka 集群、在代理中平均分配分区工作负载的建议概述。

每个优化建议均基于一组用于生成它的 优化目标,受代理资源配置的任何容量限制

所有优化的提议都是对提议重新平衡的影响的估算。您可以批准或拒绝提议。您无法在不先生成优化建议的情况下批准集群重新平衡。

您可以使用以下端点之一运行优化提议:

  • /rebalance
  • /add_broker
  • /remove_broker

14.6.1. 重新平衡端点

当您发送 POST 请求时,您可以指定重新平衡端点来生成优化建议。

/rebalance
/rebalance 端点通过在集群中的所有代理间移动副本来运行完全重新平衡。
/add_broker
add_broker 端点在扩展 Kafka 集群后通过添加一个或多个代理来使用。通常,在扩展 Kafka 集群后,新的代理仅用于托管新创建的主题的分区。如果没有创建新主题,则不会使用新添加的代理,现有代理仍保留在同一负载中。通过在向集群添加代理后立即使用 add_broker 端点,重新平衡操作会将副本从现有代理移到新添加的代理中。您可以在 POST 请求中将新代理指定为 brokerid 列表。
/remove_broker
在通过删除一个或多个代理来缩减 Kafka 集群前使用 /remove_broker 端点。如果缩减 Kafka 集群,代理也会关闭,即使它们托管副本。这可能导致复制分区不足,并可能导致某些分区处于最小 ISR 下(同步副本)。为了避免这个问题,/remove_broker 端点会将副本从要删除的代理移出。当这些代理不再托管副本时,可以安全地运行缩减操作。您可以在 POST 请求中将您要删除的代理指定为 brokerid 列表。

通常,通过在代理间分散负载,使用 /rebalance 端点来重新平衡 Kafka 集群。只有在您要扩展集群或缩减时,才使用 /add-broker 端点和 /remove_broker 端点,并相应地重新平衡副本。

运行重新平衡的步骤实际上在不同的不同的端点中相同。唯一的区别是列出添加或将被删除到请求的代理。

14.6.2. 批准或拒绝优化建议

优化建议概述显示了推荐的更改范围。通过 Cruise Control API 返回对 HTTP 请求的响应。

当您向 /rebalance 端点发出 POST 请求时,会在响应中返回一个优化建议概述。

返回优化建议概述

curl -v -X POST 'cruise-control-server:9090/kafkacruisecontrol/rebalance'

使用摘要来决定是否批准或拒绝优化提议。

批准优化建议
您可以通过向 /rebalance 端点发出 POST 请求并将 dryrun 参数设置为 false (默认值 true)来批准优化建议。Cruise Control 将提议应用到 Kafka 集群,并启动集群重新平衡操作。
拒绝优化建议
如果您选择不批准优化方案,您可以更改优化目标更新任何重新平衡性能调优选项,然后生成另一个提议。您可以在没有 dryrun 参数的情况下重新发送请求,以生成新的优化建议。

使用优化建议来评估重新平衡所需的移动。例如,概述描述了 inter-broker 和 intra-broker 移动。在独立代理间重新平衡数据。当您使用 JBOD 存储配置时,在同一代理的磁盘间移动数据重新平衡。即使您没有提前并批准提议,此类信息也很有用。

因为在重新平衡时在 Kafka 集群中出现额外的负载,您可能会拒绝优化过程或延迟其批准。

在以下示例中,建议在单独的代理间重新平衡数据。重新平衡涉及在代理间移动 55 分区副本(数据总量为 12MB)。虽然分区副本间的移动对性能有高影响,但数据总数不大。如果总数据更大,您可以拒绝提议,或者在批准重新平衡时限制对 Kafka 集群性能的影响。

重新平衡性能调优选项有助于降低数据移动的影响。如果可扩展重新平衡周期,您可以将重新平衡分成较小的批处理。一次的数据移动较少可减少集群的负载。

优化提议概述示例

Optimization has 55 inter-broker replica (12 MB) moves, 0 intra-broker
replica (0 MB) moves and 24 leadership moves with a cluster model of 5
recent windows and 100.000% of the partitions covered.
Excluded Topics: [].
Excluded Brokers For Leadership: [].
Excluded Brokers For Replica Move: [].
Counts: 3 brokers 343 replicas 7 topics.
On-demand Balancedness Score Before (78.012) After (82.912).
Provision Status: RIGHT_SIZED.

该提议还将 24 个分区领导移到不同的代理。这需要对 ZooKeeper 配置的更改,这会影响性能。

平衡分数是批准优化提议前和之后 Kafka 集群的整体平衡度量。平衡分数基于优化目标。如果满足所有目标,则分数为 100。当一个目标不满足时,分数会降低。比较均衡分数,以查看 Kafka 集群是否比重新平衡要小。

provision 状态指示当前集群配置是否支持优化目标。检查 provision 状态,以查看您应该添加或删除代理。

表 14.2. 优化提议置备状态

状态描述

RIGHT_SIZED

集群有适当数量的代理来满足优化目标。

UNDER_PROVISIONED

集群没有被置备,需要更多代理来满足优化目标。

OVER_PROVISIONED

集群已过度置备,需要较少的代理来满足优化目标。

UNDECIDED

状态无关,或者尚未决定。

14.6.3. 优化建议概述属性

下表描述了优化提议中包含的属性。

表 14.3. 优化建议概述中包含的属性

属性描述

n inter-broker replica (y MB) moves

N :将在独立代理之间移动的分区副本数量。

重新平衡操作期间的性能影响 :非常高。

y MB :移动到独立代理的每个分区副本的大小总和。

重新平衡操作期间的性能影响 :变量.集群重新平衡所需的时间越大,完成集群重新平衡所需的时间。

n intra-broker replica (y MB) moves

N :在集群代理的磁盘之间传输的分区副本数量。

重新平衡操作过程中的性能影响 :高,但小于 inter-broker 副本移动

Y MB :在同一代理的磁盘间移动的每个分区副本的大小总和。

重新平衡操作期间的性能影响 :变量.集群重新平衡所需的时间越大,完成集群重新平衡所需的时间。在同一代理的磁盘之间移动大量数据比不同的代理之间的影响要小(请参阅 内部代理移动)。

n 排除的主题

优化提议中的计算分区副本/领导移动的主题数量。

您可以使用以下方法之一排除主题:

cruisecontrol.properties 文件中指定 topics.excluded.from.partition.movement 属性中的正则表达式。

在对 /rebalance 端点的 POST 请求中,在 exclude_topics 参数中指定正则表达式。

与正则表达式匹配的主题列在响应中,并将从集群重新平衡中排除。

N 个领导移动

N :领导将切换到不同副本的分区数量。这包括对 ZooKeeper 配置的更改。

重新平衡操作期间的性能影响 :非常低。

N 个最近窗口

N :优化提议所基于的指标窗口数量。

覆盖分区的 n%

n% :优化提议涵盖的 Kafka 集群中的分区百分比。

On-demand Balancedness Score Before (nn.yyy) After (nn.yyy)

测量 Kafka 集群的整体平衡。

Cruise Control 根据多个因素(目标在 default.goal 或用户提供的目标列表中,为每一个优化目标分配了一个 Balancedness Score)。按需保证分数的计算方式为:从 100 中减去每个违反的软目标 Balancedness Score 的总和。

Before 分数基于 Kafka 集群的当前配置。After 分数基于生成的优化提议。

14.6.4. 缓存优化建议

Cruise Control 根据配置的默认优化目标维护缓存的优化建议。从工作负载模型生成,缓存的优化方案每 15 分钟更新一次,以反映 Kafka 集群的当前状态。

使用以下目标配置时,会返回最新的缓存的优化建议:

  • 默认优化目标
  • 当前缓存的提议可以满足用户提供的优化目标

要更改缓存的优化建议刷新间隔,请编辑 cruisecontrol.properties 文件中的 proposal.expiration.ms 设置。对于快速更改的集群,考虑一个较短的间隔,但这会增加 Cruise Control 服务器的负载。

14.7. 重新平衡性能调优概述

您可以为集群重新平衡调整几个性能调优选项。这些选项控制如何执行重新平衡中的分区副本和领导移动,以及分配给重新平衡操作的带宽。

分区重新分配命令

优化建议 由单独的分区重新分配命令组成。当您启动提议时,Cruise Control 服务器会将这些命令应用到 Kafka 集群。

分区重新分配命令由以下一种操作组成:

  • 分区移动 :将分区副本及其数据传输到新位置。分区移动可以采用两种形式之一:

    • Inter-broker move: 分区副本被移到不同代理上的日志目录中。
    • intra-broker move: 分区副本被移到同一代理的不同日志目录中。
  • 领导移动 :切换分区副本的领导机。

Cruise Control issues 分区重新分配命令到批处理中的 Kafka 集群。在重新平衡过程中集群的性能会受到每个批处理中包含的每种移动数量的影响。

要配置分区重新分配命令,请参阅重新平衡调整选项

副本移动策略

集群重新平衡性能也会受到 副本移动策略的影响,该策略应用到分区重新分配命令的批处理。默认情况下,Cruise Control 使用 BaseReplicaMovementStrategy,它会按照生成顺序应用命令。但是,如果提议的早期有一些非常大的分区重新分配,则此策略可能会减慢其他重新分配的应用程序。

Cruise Control 提供三个替代的副本移动策略,可用于优化提议:

  • priorityitizeSmallReplicaMovementStrategy: Order reassignments 以升序大小为单位。
  • prioritizeitizeLargeReplicaMovementStrategy: Order reassignments (降序)。
  • PostponeUrpReplicaMovementStrategy: 优先考虑为没有处于不同步状态的分区的服务的重新分配。

这些策略可以配置为序列。第一个策略尝试使用其内部逻辑比较两个分区重新分配。如果重新分配等同于,那么它将按顺序传递给下一个策略,以确定顺序等。

要配置副本移动策略,请参阅重新平衡调整选项

重新平衡调整选项

Cruise Control 提供多个配置选项用于调优重新平衡参数。这些选项采用以下方式设置:

  • 作为属性,在默认的 Cruise Control 配置中,在 cruisecontrol.properties 文件中
  • 将请求 POST 到 /rebalance 端点的参数

下表总结了这两种方法的相关配置。

表 14.4. 重新平衡性能调优配置

Cruise Control 属性KafkaRebalance 参数默认描述

num.concurrent.partition.movements.per.broker

concurrent_partition_movements_per_broker

5

每个分区重新分配批处理中的最大代理分区移动数

num.concurrent.intra.broker.partition.movements

concurrent_intra_broker_partition_movements

2

每个分区重新分配批处理中的最大 intra-broker 分区移动数

num.concurrent.leader.movements

concurrent_leader_movements

1000

每个分区重新分配批处理中的最大分区领导更改数

default.replication.throttle

replication_throttle

null (无限制)

分配给分区重新分配的带宽(以字节为单位)

default.replica.movement.strategies

replica_movement_strategies

BaseReplicaMovementStrategy

用于决定为生成的提议执行分区重新分配命令的顺序(优先级顺序)的列表。有三个策略: PrioritizeSmallReplicaMovementStrategy,PrioritizeLargeReplicaMovementStrategyPostponeUrpReplicaMovementStrategy。对于 server 设置,使用以逗号分隔的列表,包含策略类的完全限定域名(将 com.linkedin.kafka.cruisecontrol.executor.strategy. strategy 添加到每个类名称的开头)。对于重新平衡参数,请使用副本移动策略的类名称的逗号分隔列表。

更改默认设置会影响重新平衡完成所需的时间,以及重新平衡期间 Kafka 集群上的负载。使用较低值可减少负载,但会增加花费的时间,反之亦然。

其他资源

  • Cruise Control Wiki 中的配置
  • Cruise Control Wiki 中的 REST API

14.8. Cruise Control 配置

config/cruisecontrol.properties 文件包含 Cruise Control 的配置。该文件由以下类型之一的属性组成:

  • 字符串
  • Number
  • 布尔值

您可以指定并配置 Cruise Control Wiki 的 Configurations 部分中列出的所有属性。

容量配置

Cruise Control 使用 容量限制 来确定某些基于资源的优化目标是否中断。如果一个或多个基于这些资源的目标被设置为硬目标,则尝试优化会失败,然后中断。这可防止优化用于生成优化提议。

您可以在 cruise-control/config 中的以下三个 .json 文件中为 Kafka 代理资源指定容量限制:

  • capacityJBOD.json :用于 JBOD Kafka 部署(默认文件)。
  • capacity.json: 用于非JBOD Kafka 部署,每个代理都有相同的 CPU 内核数。
  • capacityCores.json: 用于在每个代理都有不同 CPU 内核数的非JBOD Kafka 部署中使用。

cruisecontrol.properties 中的 capacity.config.file 属性中设置该文件。所选文件将用于代理容量解析。例如:

capacity.config.file=config/capacityJBOD.json

可以在上述单元中为以下代理资源设置容量限制:

  • DISK: 磁盘存储(以 MB 为单位)
  • CPU :CPU 使用率作为百分比(0-100)或内核数
  • NW_IN :入站网络吞吐量(KB 每秒)
  • NW_OUT :出站网络吞吐量(KB 每秒)

要将相同的容量限制应用到由 Cruise Control 监控的每个代理,请为代理 ID -1 设置容量限制。要为单个代理设置不同的容量限制,请指定每个代理 ID 及其容量配置。

容量限制配置示例

{
  "brokerCapacities":[
    {
      "brokerId": "-1",
      "capacity": {
        "DISK": "100000",
        "CPU": "100",
        "NW_IN": "10000",
        "NW_OUT": "10000"
      },
      "doc": "This is the default capacity. Capacity unit used for disk is in MB, cpu is in percentage, network throughput is in KB."
    },
    {
      "brokerId": "0",
      "capacity": {
        "DISK": "500000",
        "CPU": "100",
        "NW_IN": "50000",
        "NW_OUT": "50000"
      },
      "doc": "This overrides the capacity for broker 0."
    }
  ]
}

如需更多信息,请参阅 在 Cruise Control Wiki 中粘贴容量 配置文件。

Cruise Control Metrics 主题的日志清理策略

非常重要的一点是,自动创建的 __CruiseControlMetrics 主题(请参阅额 auto-created topics)有一个日志清理策略 DELETE 而不是 COMPACT。否则,Cruise Control 所需的记录可能会被删除。

第 14.3 节 “部署 Cruise Control Metrics Reporter” 所述,在 Kafka 配置文件中设置以下选项可确保正确设置 COMPACT 日志清理策略:

  • cruise.control.metrics.topic.auto.create=true
  • cruise.control.metrics.topic.num.partitions=1
  • cruise.control.metrics.topic.replication.factor=1

如果在 Cruise Control Metrics Reporter 中的主题自动创建为 disabledcruise.control.metrics.topic.auto.create=false),但在 Kafka 集群中是 enabled__CruiseControlMetrics 主题仍然由代理自动创建。在这种情况下,您必须使用 kafka-configs.sh 工具将 __CruiseControlMetrics 主题的日志清理策略改为 DELETE

  1. 获取 __CruiseControlMetrics 主题的当前配置:

    opt/kafka/bin/kafka-configs.sh --bootstrap-server <broker_address> --entity-type topics --entity-name __CruiseControlMetrics --describe
  2. 更改主题配置中的日志清理策略:

    /opt/kafka/bin/kafka-configs.sh --bootstrap-server <broker_address> --entity-type topics --entity-name __CruiseControlMetrics --alter --add-config cleanup.policy=delete

如果 Cruise Control Metrics Reporter Kafka 集群中都 禁用了 主题自动创建,您必须手动创建 __CruiseControlMetrics 主题,然后使用 kafka-configs.sh 工具将其配置为使用 DELETE 日志清理策略。

更多信息请参阅 第 7.9 节 “修改主题配置”

日志记录配置

Cruise Control 将 log4j1 用于所有服务器日志记录。要更改默认配置,请编辑 /opt/cruise-control/config/log4j.properties 文件中的 log4j.properties 文件。

您必须在更改生效前重启 Cruise Control 服务器。

14.9. 生成优化建议

当您向 /rebalance 端点发出 POST 请求时,Cruise Control 会生成优化建议,以根据提供的优化目标重新平衡 Kafka 集群。您可以使用优化提议的结果来重新平衡 Kafka 集群。

您可以使用以下端点之一运行优化提议:

  • /rebalance
  • /add_broker
  • /remove_broker

您使用的端点取决于您是否正在在 Kafka 集群中已在运行的所有代理进行重新平衡 ; 或者要在扩展后或缩减 Kafka 集群前重新平衡。如需更多信息,请参阅使用代理扩展 重新平衡端点

优化建议作为空运行方式生成,除非提供了 dryrun 参数,并将其设置为 false。在 "dry run mode" 中,Cruise Control 生成优化提议和预计结果,但不通过重新平衡集群来启动提议。

您可以分析优化建议返回的信息,并决定是否批准它。

使用以下参数向端点发出请求:

dryRun

类型:布尔值,默认: true

告知 Cruise Control 是否要只生成优化提议(true),或者生成优化建议并执行集群重新平衡(false)。

dryrun=true (默认)时,您还可以传递 verbose 参数,以返回有关 Kafka 集群状态的更多详细信息。这包括应用优化提议前和之后每个 Kafka 代理上的负载指标,以及值 before 和 after 值之间的区别。

excluded_topics

类型: regex

与从优化提议计算中排除的主题匹配的正则表达式。

目标

type: 字符串列表,默认为配置的 default.goals 列表

用户提供的优化目标列表,用于准备优化方法。如果没有提供目标,则使用 cruisecontrol.properties 文件中配置的 default.goals 列表。

skip_hard_goals_check

type: boolean, default: false

默认情况下,Cruise Control 检查用户提供的优化目标(在 goals 参数中)是否包含所有配置的硬目标(在 hard.goals中)。如果您提供不是配置的 hard.goals 子集的目标,请求会失败。

如果要生成不使用所有配置的 hard.goals 优化目标,则将 skip_hard_goals_check 设置为 true

json

type: boolean, default: false

控制 Cruise Control 服务器返回的响应类型。如果没有提供,或者设置为 false,则 Cruise Control 会返回文本格式以便在命令行中显示。如果要以编程方式提取返回的信息的元素,请设置 json=true。这将返回 JSON 格式的文本,这些文本可以传送到 jq 等工具,或在脚本和程序中解析它们。

详细

type: boolean, default: false

控制 Cruise Control 服务器返回的响应中详细级别。可与 dryrun=true 一起使用。

注意

其他参数可用。如需更多信息,请参阅 Cruise Control Wiki 中的 REST API

先决条件

  • Kafka 和 ZooKeeper 正在运行
  • Cruise Control 正在运行
  • (可选进行扩展)已 在主机上安装新代理,以便包含在重新平衡中

流程

  1. 使用对 /rebalance/add_broker/remove_broker 端点的 POST 请求来生成优化建议。

    使用默认目标对 /rebalance 的请求示例

    curl -v -X POST 'cruise-control-server:9090/kafkacruisecontrol/rebalance'

    缓存的优化建议会立即返回。

    注意

    如果返回 NotEnoughValidWindows,Cruise Control 尚未记录足够的指标数据,以生成优化器。等待几分钟,然后重新发送请求。

    使用指定目标向 /rebalance 的请求示例

    curl -v -X POST 'cruise-control-server:9090/kafkacruisecontrol/rebalance?goals=RackAwareGoal,ReplicaCapacityGoal'

    如果请求满足所提供的目标,则缓存的优化建议会立即返回。否则,会使用提供的目标生成一个新的优化建议;这需要更长的时间计算。您可以通过在请求中添加 ignore_proposal_cache=true 参数来强制实施此行为。

    在没有硬目标的情况下,使用指定目标对 /rebalance 的请求示例

    curl -v -X POST 'cruise-control-server:9090/kafkacruisecontrol/rebalance?goals=RackAwareGoal,ReplicaCapacityGoal,ReplicaDistributionGoal&skip_hard_goal_check=true'

    包含指定代理的 /add_broker 请求示例

    curl -v -X POST 'cruise-control-server:9090/kafkacruisecontrol/add_broker?brokerid=3,4'

    请求只包含新代理的 ID。例如,此请求添加了 ID 为 34 的代理。在重新平衡时,副本会从现有代理移到新代理中。

    对排除指定代理的 /remove_broker 的请求示例

    curl -v -X POST 'cruise-control-server:9090/kafkacruisecontrol/remove_broker?brokerid=3,4'

    请求只包含仅排除的代理的 ID。例如,此请求排除 ID 为 34 的代理。在重新平衡时,副本会从被移除的代理移到其他现有代理中。

    注意

    如果正在移除的代理带有排除的主题,则副本仍会移动。

  2. 查看响应中包含的优化建议。属性描述了待处理的集群重新平衡操作。

    提议包含所提出优化的高级概述,以及各个默认优化目标的总结,以及执行过程后的预期集群状态。

    请特别注意以下信息:

    • 重新平衡后的集群负载。如果满足您的要求,您应该使用高级别概述来评估提议的更改的影响。
    • n inter-broker replica (y MB) moves 表示在代理间移动多少数据。数值越大,重新平衡过程中对 Kafka 集群的潜在性能影响越大。
    • n intra-broker replica (y MB) moves 表示在代理本身(磁盘)中移动多少数据。数值越大,对各个代理的潜在性能影响越大(尽管小于 n inter-broker replica (y MB) moves)。
    • 领导的移动数量。这在重新平衡过程中对集群的性能产生不计影响。

异步响应

默认情况下,Cruise Control REST API 端点超时会在 10 秒后超时,虽然建议生成在服务器上继续。如果最新缓存的优化器尚未就绪,或者用户提供的优化目标是通过 ignore_proposal_cache=true 指定,则可能会出现超时。

要允许您稍后检索优化过程,请记录请求的唯一标识符,该标识符在 /rebalance 端点的响应标头中提供。

要使用 curl 获取响应,请指定详细(-v)选项:

curl -v -X POST 'cruise-control-server:9090/kafkacruisecontrol/rebalance'

以下是标头示例:

* Connected to cruise-control-server (::1) port 9090 (#0)
> POST /kafkacruisecontrol/rebalance HTTP/1.1
> Host: cc-host:9090
> User-Agent: curl/7.70.0
> Accept: /
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Date: Mon, 01 Jun 2020 15:19:26 GMT
< Set-Cookie: JSESSIONID=node01wk6vjzjj12go13m81o7no5p7h9.node0; Path=/
< Expires: Thu, 01 Jan 1970 00:00:00 GMT
< User-Task-ID: 274b8095-d739-4840-85b9-f4cfaaf5c201
< Content-Type: text/plain;charset=utf-8
< Cruise-Control-Version: 2.0.103.redhat-00002
< Cruise-Control-Commit_Id: 58975c9d5d0a78dd33cd67d4bcb497c9fd42ae7c
< Content-Length: 12368
< Server: Jetty(9.4.26.v20200117-redhat-00001)

如果优化建议不在超时内就绪,您可以重新提交 POST 请求,这一次在标头中包括原始请求的 User-Task-ID

curl -v -X POST -H 'User-Task-ID: 274b8095-d739-4840-85b9-f4cfaaf5c201' 'cruise-control-server:9090/kafkacruisecontrol/rebalance'

14.10. 批准优化建议

如果您对最近生成的优化器满意,您可以指示 Cruise Control 启动集群重新平衡并开始重新分配分区。

在生成优化建议和启动集群重新平衡之间尽可能少的时间。如果因为您生成了原始优化提议,集群状态可能会改变。因此,启动的集群重新平衡可能与您检查的不同。如果有疑问,首先会生成一个新的优化建议。

在一个集群重新平衡,状态为 "Active",一次只能进行。

先决条件

流程

  1. 使用 dryrun=false 参数向 /rebalance/add_broker/remove_broker 端点发送 POST 请求:

    如果您使用 /add_broker/remove_broker 端点来生成包含或排除代理的提议,请使用同一端点执行使用或未指定代理的重新平衡。

    /rebalance的请求示例

    curl -X POST 'cruise-control-server:9090/kafkacruisecontrol/rebalance?dryrun=false'

    /add_broker的请求示例

    curl -v -X POST 'cruise-control-server:9090/kafkacruisecontrol/add_broker?dryrun=false&brokerid=3,4'

    /remove_broker的请求示例

    curl -v -X POST 'cruise-control-server:9090/kafkacruisecontrol/remove_broker?dryrun=false&brokerid=3,4'

    Cruise Control 启动集群重新平衡并返回优化提议。

  2. 检查优化建议中总结的更改。如果更改不是您期望的 ,您可以停止重新平衡
  3. 使用 /user_tasks 端点检查集群重新平衡的进度。集群重新平衡状态为 "Active"。

    查看在 Cruise Control 服务器上执行的所有集群重新平衡任务:

    curl 'cruise-control-server:9090/kafkacruisecontrol/user_tasks'
    
    USER TASK ID      CLIENT ADDRESS  START TIME     STATUS  REQUEST URL
    c459316f-9eb5-482f-9d2d-97b5a4cd294d  0:0:0:0:0:0:0:1       2020-06-01_16:10:29 UTC  Active      POST /kafkacruisecontrol/rebalance?dryrun=false
    445e2fc3-6531-4243-b0a6-36ef7c5059b4  0:0:0:0:0:0:0:1       2020-06-01_14:21:26 UTC  Completed   GET /kafkacruisecontrol/state?json=true
    05c37737-16d1-4e33-8e2b-800dee9f1b01  0:0:0:0:0:0:0:1       2020-06-01_14:36:11 UTC  Completed   GET /kafkacruisecontrol/state?json=true
    aebae987-985d-4871-8cfb-6134ecd504ab  0:0:0:0:0:0:0:1       2020-06-01_16:10:04 UTC
  4. 要查看特定集群重新平衡任务的状态,请提供 user-task-ids 参数和任务 ID:

    curl 'cruise-control-server:9090/kafkacruisecontrol/user_tasks?user_task_ids=c459316f-9eb5-482f-9d2d-97b5a4cd294d'

(可选)在缩减时删除代理

成功重新平衡后,您可以停止您排除的任何代理,以缩减 Kafka 集群。

  1. 检查正在删除的每个代理在其日志中没有任何实时分区(log.dirs)。

    ls -l <LogDir> | grep -E '^d' | grep -vE '[a-zA-Z0-9.-]+\.[a-z0-9]+-delete$'

    如果日志目录与正则表达式 \.[a-z0-9]-delete$ 不匹配,则仍然存在活跃的分区。如果您有活跃的分区,请检查重新平衡已完成,或配置优化建议。您可以再次运行提议。在继续下一步前,请确保没有活跃的分区。

  2. 停止代理。

    su - kafka
    /opt/kafka/bin/kafka-server-stop.sh
  3. 确认代理已停止。

    jcmd | grep kafka

14.11. 停止活跃的集群重新平衡

您可以停止当前正在进行的集群重新平衡。

这指示 Cruise Control 完成当前的分区重新分配批处理,然后停止重新平衡。当停止重新平衡后,已完成的分区重新分配已经被应用;因此,在重新平衡操作开始前 Kafka 集群的状态会有所不同。如果需要进一步重新平衡,您应该生成新的优化建议。

注意

在 intermediate(停止)状态中的 Kafka 集群的性能可能比初始状态更糟。

先决条件

  • 集群重新平衡正在进行(由 "Active" 状态表示)。

流程

  • 发送 POST 请求到 /stop_proposal_execution 端点:

    curl -X POST 'cruise-control-server:9090/kafkacruisecontrol/stop_proposal_execution'

其他资源

第 15 章 使用分区重新分配工具

在扩展 Kafka 集群时,您可能需要添加或删除代理并更新分区分布或主题复制因素。要更新分区和主题,您可以使用 kafka-reassign-partitions.sh 工具。

您可以使用 kafka-reassign-partitions.sh 工具更改主题的复制因素。该工具也可用于重新分配分区并在代理间平衡分区分布,以提高性能。但是,建议使用 Cruise Control 自动分区重新分配和集群重新平衡。Cruise Control 可以在没有任何停机时间的情况下将主题从一个代理移到另一个代理,它是重新分配分区的最有效方法。AMQ Streams Cruise Control 集成不支持更改主题的复制因素。

15.1. 分区重新分配工具概述

分区重新分配工具提供以下功能来管理 Kafka 分区和代理:

重新分发分区副本
通过添加或删除代理来扩展集群,并将 Kafka 分区从大量加载的代理移到使用不足的代理。要做到这一点,您必须创建一个分区重新分配计划,以标识要移动的主题和分区以及移动它们的位置。对于这种类型的操作,建议使用 Cruise Control,因为它 自动执行集群重新平衡过程
扩展主题复制因素和缩减
增加或减少 Kafka 主题的复制因素。要做到这一点,您必须创建一个分区重新分配计划,以标识分区之间的现有复制分配,以及使用复制因素更改的更新分配。
更改首选领导
更改 Kafka 分区的首选领导。如果当前首选领导不可用或者您要在集群中在代理间重新分发负载,这非常有用。要做到这一点,您必须创建一个分区重新分配计划,该计划通过更改副本顺序来指定每个分区的新首选领导。
将日志目录更改为使用特定的 JBOD 卷
将 Kafka 代理的日志目录更改为使用特定的 JBOD 卷。如果要将 Kafka 数据移动到不同的磁盘或存储设备中,这非常有用。要做到这一点,您必须创建一个分区重新分配计划,用于指定每个主题的新日志目录。

15.1.1. 生成分区重新分配计划

分区重新分配工具(kafka-reassign-partitions.sh)的工作原理,方法是生成一个分区分配计划,指定哪些分区应从其当前代理移到新代理中。

如果您对计划满意,您可以执行它。然后该工具执行以下操作:

  • 将分区数据迁移到新代理
  • 更新 Kafka 代理的元数据以反映新分区分配
  • 触发 Kafka 代理滚动重启,以确保新分配生效

分区重新分配工具有三种不同的模式:

--generate
采用一组主题和代理并生成 重新分配 JSON 文件,该文件将导致将这些主题的分区分配给这些代理。由于这在整个主题上运行,因此当您只想重新分配某些主题分区时无法使用它。
--execute
采用 重新分配 JSON 文件,并将其应用到集群中的分区和代理。由于因为分区领导者成为分区领导者而获得分区的代理。对于给定分区,新代理发现并加入 ISR (同步副本)后,旧代理将停止后续代理,并删除其副本。
--verify
使用与 --execute 步骤相同的 重新分配 JSON 文件,-- verify 会检查文件中所有分区是否已移至其预期的代理中。如果重新分配完成,-- verify 也会删除所有生效的流量节流(-throttle)。除非被删除,即使重新分配完成,节流将继续对集群的影响。

在任意给定时间,集群中只能有一个重新分配,且无法取消正在运行的重新分配。如果需要取消重新分配,请等待它完成,然后执行另一个重新分配来恢复第一个重新分配的影响。kafka-reassign-partitions.sh 将打印这个 reversion 的重新分配 JSON 作为其输出的一部分。非常大的重新分配应该被分解为多个较小的重新分配,以防需要停止 in-progress 重新分配。

15.1.2. 在分区重新分配 JSON 文件中指定主题

kafka-reassign-partitions.sh 工具使用一个重新分配 JSON 文件来指定要重新分配的主题。如果要移动特定的分区,您可以生成重新分配 JSON 文件或手动创建文件。

基本重新分配 JSON 文件在以下示例中显示的结构,它描述了属于两个 Kafka 主题的三个分区。每个分区被重新分配给一组新的副本,这些副本由代理 ID 标识。需要 版本主题分区副本 属性。

分区重新分配 JSON 文件结构示例

{
  "version": 1, 1
  "partitions": [ 2
    {
      "topic": "example-topic-1", 3
      "partition": 0, 4
      "replicas": [1, 2, 3] 5
    },
    {
      "topic": "example-topic-1",
      "partition": 1,
      "replicas": [2, 3, 4]
    },
    {
      "topic": "example-topic-2",
      "partition": 0,
      "replicas": [3, 4, 5]
    }
  ]
}

1
重新分配 JSON 文件格式的版本。目前,只支持版本 1,因此这应该始终为 1。
2
指定要重新分配的分区的数组。
3
分区所属的 Kafka 主题的名称。
4
正在重新分配的分区 ID。
5
应该分配给这个分区副本的代理 ID 的排序数组。列表中的第一个代理是领导副本。
注意

未包含在 JSON 中的分区不会改变。

如果您只使用主题数组指定 主题,则分区重新分配工具会重新分配属于指定主题的所有分区。

重新分配 JSON 文件结构示例,用于重新分配主题的所有分区

{
  "version": 1,
  "topics": [
    { "topic": "my-topic"}
  ]
}

15.1.3. 在 JBOD 卷间重新分配分区

在 Kafka 集群中使用 JBOD 存储时,您可以在特定卷及其日志目录间重新分配分区(每个卷都有一个日志目录)。

要将分区重新分配给特定卷,请在重新分配 JSON 文件中为每个分区添加 log_dirs 值。每个 log_dirs 数组包含与 replicas 数组相同的条目数量,因为每个副本都应该分配给特定的日志目录。log_dirs 数组包含到日志目录的绝对路径或 特殊值任何 值表示 Kafka 可以为该副本选择任何可用的日志目录,这在 JBOD 卷间重新分配分区时非常有用。

使用日志目录重新分配 JSON 文件结构示例

{
  "version": 1,
  "partitions": [
    {
      "topic": "example-topic-1",
      "partition": 0,
      "replicas": [1, 2, 3]
      "log_dirs": ["/var/lib/kafka/data-0/kafka-log1", "any", "/var/lib/kafka/data-1/kafka-log2"]
    },
    {
      "topic": "example-topic-1",
      "partition": 1,
      "replicas": [2, 3, 4]
      "log_dirs": ["any",  "/var/lib/kafka/data-2/kafka-log3", "/var/lib/kafka/data-3/kafka-log4"]
    },
    {
      "topic": "example-topic-2",
      "partition": 0,
      "replicas": [3, 4, 5]
      "log_dirs": ["/var/lib/kafka/data-4/kafka-log5", "any",  "/var/lib/kafka/data-5/kafka-log6"]
    }
  ]
}

15.1.4. 分区重新分配节流

分区重新分配可能会是一个较慢的过程,因为它涉及在代理间传输大量数据。为了避免对客户端造成负面影响,您可以节流重新分配过程。使用带有 kafka-reassign-partitions.sh 工具的 --throttle 参数来节流重新分配。您可以为代理之间的分区移动指定每秒的最大阈值(以字节为单位)。例如,-- throttle 5000000 为移动 50 MBps 的分区设置最大阈值。

节流可能会导致重新分配更长的时间完成。

  • 如果节流太低,则新分配的代理将无法与发布的记录保持同步,且重新分配永远不会完成。
  • 如果节流过高,客户端将会受到影响。

例如,对于生成者,这可能会清单高于等待确认的正常延迟。对于消费者,这可能会导致在轮询之间延迟更高的延迟导致的吞吐量下降。

15.2. 添加代理后重新分配分区

在增加 Kafka 集群中的代理数量后,使用 kafka-reassign-partitions.sh 工具生成的重新分配文件来重新分配分区。重新分配文件应描述如何将分区重新分配给 enlarged Kafka 集群中的代理。您可以将文件中指定的重新分配应用到代理,然后验证新分区分配。

此流程描述了使用 TLS 的安全扩展流程。您需要一个使用 TLS 加密和 mTLS 身份验证的 Kafka 集群。

注意

虽然您可以使用 kafka-reassign-partitions.sh 工具,但推荐对自动 分区重新分配和集群重新平衡进行 Cruise Control。Cruise Control 可以在没有任何停机时间的情况下将主题从一个代理移到另一个代理,它是重新分配分区的最有效方法。

先决条件

  • 现有的 Kafka 集群。
  • 安装了 额外 AMQ 代理的新机器。
  • 您已创建了 JSON 文件,以指定如何将分区重新分配给放大集群中的代理。

    在此过程中,我们重新分配了名为 my-topic 的主题的所有分区。名为 topics.json 的 JSON 文件指定主题,用于生成 reassignment.json 文件。

JSON 文件示例指定 my-topic

{
  "version": 1,
  "topics": [
    { "topic": "my-topic"}
  ]
}

流程

  1. 使用与集群中其他代理相同的设置为新代理创建配置文件,但 broker.id 除外,它应该是未被任何其他代理使用的数字。
  2. 启动新的 Kafka 代理,将您在上一步中创建的配置文件作为参数传递给 kafka-server-start.sh 脚本:

    su - kafka
    /opt/kafka/bin/kafka-server-start.sh -daemon /opt/kafka/config/server.properties
  3. 验证 Kafka 代理是否正在运行。

    jcmd | grep Kafka
  4. 为每个新代理重复上述步骤。
  5. 如果没有这样做,请使用 kafka-reassign-partitions.sh 工具生成名为 reassignment.json 的重新分配 JSON 文件。

    生成重新分配 JSON 文件的命令示例

    /opt/kafka/bin/kafka-reassign-partitions.sh \
      --bootstrap-server localhost:9092 \
      --topics-to-move-json-file topics.json \ 1
      --broker-list 0,1,2,3,4 \ 2
      --generate

    1
    指定主题的 JSON 文件。
    2
    kafka 集群中的代理 ID,以包含在操作中。这假设添加了代理 4

    显示当前和建议的副本分配的重新分配 JSON 文件示例

    Current partition replica assignment
    {"version":1,"partitions":[{"topic":"my-topic","partition":0,"replicas":[0,1,2],"log_dirs":["any","any","any"]},{"topic":"my-topic","partition":1,"replicas":[1,2,3],"log_dirs":["any","any","any"]},{"topic":"my-topic","partition":2,"replicas":[2,3,0],"log_dirs":["any","any","any"]}]}
    
    Proposed partition reassignment configuration
    {"version":1,"partitions":[{"topic":"my-topic","partition":0,"replicas":[0,1,2,3],"log_dirs":["any","any","any","any"]},{"topic":"my-topic","partition":1,"replicas":[1,2,3,4],"log_dirs":["any","any","any","any"]},{"topic":"my-topic","partition":2,"replicas":[2,3,4,0],"log_dirs":["any","any","any","any"]}]}

    如果需要稍后恢复更改,在本地保存此文件的副本。

  6. 使用 --execute 选项运行分区重新分配。

    /opt/kafka/bin/kafka-reassign-partitions.sh \
      --bootstrap-server localhost:9092 \
      --reassignment-json-file reassignment.json \
      --execute

    如果您要节流复制,也可以使用每秒的 throttle 节流率传递 --throttle 选项。例如:

    /opt/kafka/bin/kafka-reassign-partitions.sh \
      --bootstrap-server localhost:9092 \
      --reassignment-json-file reassignment.json \
      --throttle 5000000 \
      --execute
  7. 使用 --verify 选项验证重新分配是否已完成。

    /opt/kafka/bin/kafka-reassign-partitions.sh \
      --bootstrap-server localhost:9092 \
      --reassignment-json-file reassignment.json \
      --verify

    --verify 命令报告正在移动的每个分区都成功完成时,重新分配已完成。最后 --verify 也会导致删除任何重新分配节流的影响。

15.3. 在删除代理前重新分配分区

在减少 Kafka 集群中的代理数量前,使用 kafka-reassign-partitions.sh 工具生成的重新分配文件来重新分配分区。重新分配文件必须描述如何将分区重新分配给 Kafka 集群中的其余代理。您可以将文件中指定的重新分配应用到代理,然后验证新分区分配。最高数字 pod 中的代理会首先被删除。

此流程描述了使用 TLS 的安全扩展流程。您需要一个使用 TLS 加密和 mTLS 身份验证的 Kafka 集群。

注意

虽然您可以使用 kafka-reassign-partitions.sh 工具,但推荐对自动 分区重新分配和集群重新平衡进行 Cruise Control。Cruise Control 可以在没有任何停机时间的情况下将主题从一个代理移到另一个代理,它是重新分配分区的最有效方法。

先决条件

  • 现有的 Kafka 集群。
  • 您已创建了 JSON 文件,以指定如何将分区重新分配给减少集群中的代理。

    在此过程中,我们重新分配了名为 my-topic 的主题的所有分区。名为 topics.json 的 JSON 文件指定主题,用于生成 reassignment.json 文件。

JSON 文件示例指定 my-topic

{
  "version": 1,
  "topics": [
    { "topic": "my-topic"}
  ]
}

流程

  1. 如果没有这样做,请使用 kafka-reassign-partitions.sh 工具生成名为 reassignment.json 的重新分配 JSON 文件。

    生成重新分配 JSON 文件的命令示例

    /opt/kafka/bin/kafka-reassign-partitions.sh \
      --bootstrap-server localhost:9092 \
      --topics-to-move-json-file topics.json \ 1
      --broker-list 0,1,2,3 \ 2
      --generate

    1
    指定主题的 JSON 文件。
    2
    kafka 集群中的代理 ID,以包含在操作中。这假设代理 4 已被删除。

    显示当前和建议的副本分配的重新分配 JSON 文件示例

    Current partition replica assignment
    {"version":1,"partitions":[{"topic":"my-topic","partition":0,"replicas":[3,4,2,0],"log_dirs":["any","any","any","any"]},{"topic":"my-topic","partition":1,"replicas":[0,2,3,1],"log_dirs":["any","any","any","any"]},{"topic":"my-topic","partition":2,"replicas":[1,3,0,4],"log_dirs":["any","any","any","any"]}]}
    
    Proposed partition reassignment configuration
    {"version":1,"partitions":[{"topic":"my-topic","partition":0,"replicas":[0,1,2],"log_dirs":["any","any","any"]},{"topic":"my-topic","partition":1,"replicas":[1,2,3],"log_dirs":["any","any","any"]},{"topic":"my-topic","partition":2,"replicas":[2,3,0],"log_dirs":["any","any","any"]}]}

    如果需要稍后恢复更改,在本地保存此文件的副本。

  2. 使用 --execute 选项运行分区重新分配。

    /opt/kafka/bin/kafka-reassign-partitions.sh \
      --bootstrap-server localhost:9092 \
      --reassignment-json-file reassignment.json \
      --execute

    如果您要节流复制,也可以使用每秒的 throttle 节流率传递 --throttle 选项。例如:

    /opt/kafka/bin/kafka-reassign-partitions.sh \
      --bootstrap-server localhost:9092 \
      --reassignment-json-file reassignment.json \
      --throttle 5000000 \
      --execute
  3. 使用 --verify 选项验证重新分配是否已完成。

    /opt/kafka/bin/kafka-reassign-partitions.sh \
      --bootstrap-server localhost:9092 \
      --reassignment-json-file reassignment.json \
      --verify

    --verify 命令报告正在移动的每个分区都成功完成时,重新分配已完成。最后 --verify 也会导致删除任何重新分配节流的影响。

  4. 检查正在删除的每个代理在其日志中没有任何实时分区(log.dirs)。

    ls -l <LogDir> | grep -E '^d' | grep -vE '[a-zA-Z0-9.-]+\.[a-z0-9]+-delete$'

    如果日志目录与正则表达式 \.[a-z0-9]-delete$ 不匹配,则仍然存在活跃的分区。如果您有活跃的分区,检查重新分配已完成,或者在重新分配 JSON 文件中的配置。您可以再次运行重新分配。在继续下一步前,请确保没有活跃的分区。

  5. 停止代理。

    su - kafka
    /opt/kafka/bin/kafka-server-stop.sh
  6. 确认 Kafka 代理已停止。

    jcmd | grep kafka

15.4. 更改主题的复制因素

使用 kafka-reassign-partitions.sh 工具更改 Kafka 集群中主题的复制因素。这可以通过重新分配文件来描述主题副本是如何更改的。

先决条件

  • 现有的 Kafka 集群。
  • 您已创建了 JSON 文件,以指定操作中包含的主题。

    在此过程中,名为 my-topic 的主题有 4 个副本,我们希望将其减少到 3。名为 topics.json 的 JSON 文件指定主题,用于生成 reassignment.json 文件。

JSON 文件示例指定 my-topic

{
  "version": 1,
  "topics": [
    { "topic": "my-topic"}
  ]
}

流程

  1. 如果没有这样做,请使用 kafka-reassign-partitions.sh 工具生成名为 reassignment.json 的重新分配 JSON 文件。

    生成重新分配 JSON 文件的命令示例

    /opt/kafka/bin/kafka-reassign-partitions.sh \
      --bootstrap-server localhost:9092 \
      --topics-to-move-json-file topics.json \ 1
      --broker-list 0,1,2,3,4 \ 2
      --generate

    1
    指定主题的 JSON 文件。
    2
    kafka 集群中的代理 ID,以包含在操作中。

    显示当前和建议的副本分配的重新分配 JSON 文件示例

    Current partition replica assignment
    {"version":1,"partitions":[{"topic":"my-topic","partition":0,"replicas":[3,4,2,0],"log_dirs":["any","any","any","any"]},{"topic":"my-topic","partition":1,"replicas":[0,2,3,1],"log_dirs":["any","any","any","any"]},{"topic":"my-topic","partition":2,"replicas":[1,3,0,4],"log_dirs":["any","any","any","any"]}]}
    
    Proposed partition reassignment configuration
    {"version":1,"partitions":[{"topic":"my-topic","partition":0,"replicas":[0,1,2,3],"log_dirs":["any","any","any","any"]},{"topic":"my-topic","partition":1,"replicas":[1,2,3,4],"log_dirs":["any","any","any","any"]},{"topic":"my-topic","partition":2,"replicas":[2,3,4,0],"log_dirs":["any","any","any","any"]}]}

    如果需要稍后恢复更改,在本地保存此文件的副本。

  2. 编辑 reassignment.json,以从每个分区中删除副本。

    例如,使用 jq 删除主题的每个分区列表中的最后一个副本:

    删除每个分区的最后一个主题副本

    jq '.partitions[].replicas |= del(.[-1])' reassignment.json > reassignment.json

    显示更新的副本的重新分配文件示例

    {"version":1,"partitions":[{"topic":"my-topic","partition":0,"replicas":[0,1,2],"log_dirs":["any","any","any","any"]},{"topic":"my-topic","partition":1,"replicas":[1,2,3],"log_dirs":["any","any","any","any"]},{"topic":"my-topic","partition":2,"replicas":[2,3,4],"log_dirs":["any","any","any","any"]}]}

  3. 使用 --execute 选项进行主题副本更改。

    /opt/kafka/bin/kafka-reassign-partitions.sh \
      --bootstrap-server localhost:9092 \
      --reassignment-json-file reassignment.json \
      --execute
    注意

    从代理中删除副本不需要任何代理数据移动,因此无需节流复制。如果要添加副本,您可能需要更改节流率。

  4. 使用 --verify 选项,验证对主题副本的更改是否已完成。

    /opt/kafka/bin/kafka-reassign-partitions.sh \
      --bootstrap-server localhost:9092 \
      --reassignment-json-file reassignment.json \
      --verify

    --verify 命令报告正在移动的每个分区都成功完成时,重新分配已完成。最后 --verify 也会导致删除任何重新分配节流的影响。

  5. 使用 --describe 选项运行 bin/kafka-topics.sh 命令,以查看对主题的更改的结果。

    /opt/kafka/bin/kafka-reassign-partitions.sh \
      --bootstrap-server localhost:9092 \
      --describe

    减少主题副本数的结果

    my-topic  Partition: 0  Leader: 0  Replicas: 0,1,2 Isr: 0,1,2
    my-topic  Partition: 1  Leader: 2  Replicas: 1,2,3 Isr: 1,2,3
    my-topic  Partition: 2  Leader: 3  Replicas: 2,3,4 Isr: 2,3,4

第 16 章 使用 Kerberos (GSSAPI)身份验证

AMQ Streams 支持使用 Kerberos (GSSAPI)身份验证协议来保护对 Kafka 集群的单点登录访问。GSSAPI 是 Kerberos 功能的 API 打包程序,从底层实施中模拟应用程序。

Kerberos 是一种网络身份验证系统,其允许客户端和服务器使用对称加密和信任的第三方 KDC 来互相进行身份验证。

16.1. 将 AMQ Streams 设置为使用 Kerberos (GSSAPI)身份验证

此流程演示了如何配置 AMQ Streams,以便 Kafka 客户端可以使用 Kerberos (GSSAPI)身份验证访问 Kafka 和 ZooKeeper。

该流程假设已在 Red Hat Enterprise Linux 主机上设置了 Kerberos krb5 资源服务器。

该流程显示如何配置:

  1. 服务主体
  2. Kafka 代理使用 Kerberos 登录
  3. zookeeper 使用 Kerberos 登录
  4. 使用 Kerberos 身份验证访问 Kafka 的制作者和消费者客户端

这些说明描述了在单个主机上安装单个 ZooKeeper 和 Kafka 的 Kerberos 设置,以及生成者和消费者客户端的额外配置。

先决条件

要配置 Kafka 和 ZooKeeper 以验证和授权 Kerberos 凭证,您需要:

  • 访问 Kerberos 服务器
  • 每个 Kafka 代理主机上的 Kerberos 客户端

有关在代理主机上设置 Kerberos 服务器和客户端的详情请参考 RHEL 设置配置中的 Kerberos 示例

添加用于身份验证的服务主体

在 Kerberos 服务器中,为 ZooKeeper、Kafka 代理和 Kafka 生成者和消费者客户端创建服务主体(用户)。

服务主体必须采用 SERVICE-NAME/FULLY-QUALIFIED-HOST-NAME@DOMAIN-REALM 的形式。

  1. 通过 Kerberos KDC 创建存储主体密钥的服务主体和 keytab。

    例如:

    • zookeeper/node1.example.redhat.com@EXAMPLE.REDHAT.COM
    • kafka/node1.example.redhat.com@EXAMPLE.REDHAT.COM
    • producer1/node1.example.redhat.com@EXAMPLE.REDHAT.COM
    • consumer1/node1.example.redhat.com@EXAMPLE.REDHAT.COM

      ZooKeeper 服务主体必须与 Kafka config/server.properties 文件中的 zookeeper.connect 配置具有相同的主机名:

      zookeeper.connect=node1.example.redhat.com:2181

      如果主机名不同,则使用 localhost,并且身份验证将失败。

  2. 在主机上创建一个目录并添加 keytab 文件:

    例如:

    /opt/kafka/krb5/zookeeper-node1.keytab
    /opt/kafka/krb5/kafka-node1.keytab
    /opt/kafka/krb5/kafka-producer1.keytab
    /opt/kafka/krb5/kafka-consumer1.keytab
  3. 确保 kafka 用户可以访问该目录:

    chown kafka:kafka -R /opt/kafka/krb5

将 ZooKeeper 配置为使用 Kerberos 登录

配置 ZooKeeper 以使用 Kerberos 密钥分发中心(KDC)使用之前为 zookeeper 创建的用户主体和 keytabs 进行身份验证。

  1. 创建或修改 opt/kafka/config/jaas.conf 文件来支持 ZooKeeper 客户端和服务器操作:

    Client {
        com.sun.security.auth.module.Krb5LoginModule required debug=true
        useKeyTab=true 1
        storeKey=true 2
        useTicketCache=false 3
        keyTab="/opt/kafka/krb5/zookeeper-node1.keytab" 4
        principal="zookeeper/node1.example.redhat.com@EXAMPLE.REDHAT.COM"; 5
    };
    
    Server {
        com.sun.security.auth.module.Krb5LoginModule required debug=true
        useKeyTab=true
        storeKey=true
        useTicketCache=false
        keyTab="/opt/kafka/krb5/zookeeper-node1.keytab"
        principal="zookeeper/node1.example.redhat.com@EXAMPLE.REDHAT.COM";
    };
    
    QuorumServer {
        com.sun.security.auth.module.Krb5LoginModule required debug=true
        useKeyTab=true
        storeKey=true
        keyTab="/opt/kafka/krb5/zookeeper-node1.keytab"
        principal="zookeeper/node1.example.redhat.com@EXAMPLE.REDHAT.COM";
    };
    
    QuorumLearner {
        com.sun.security.auth.module.Krb5LoginModule required debug=true
        useKeyTab=true
        storeKey=true
        keyTab="/opt/kafka/krb5/zookeeper-node1.keytab"
        principal="zookeeper/node1.example.redhat.com@EXAMPLE.REDHAT.COM";
    };
    1
    设置为 true,以从 keytab 获取主体密钥。
    2
    设置为 true 以存储主体密钥。
    3
    设置为 true,以从票据缓存获取 Ticket Granting Ticket (TGT)。
    4
    keyTab 属性指向从 Kerberos KDC 复制的 keytab 文件的位置。location 和 file 必须可以被 kafka 用户读取。
    5
    principal 属性配置为与 KDC 主机上创建的完全限定域名匹配,其格式是 SERVICE-NAME/FULLY-QUALIFIED-HOST@DOMAIN-NAME
  2. 编辑 opt/kafka/config/zookeeper.properties 以使用更新的 JAAS 配置:

    # ...
    
    requireClientAuthScheme=sasl
    jaasLoginRenew=3600000 1
    kerberos.removeHostFromPrincipal=false 2
    kerberos.removeRealmFromPrincipal=false 3
    quorum.auth.enableSasl=true 4
    quorum.auth.learnerRequireSasl=true 5
    quorum.auth.serverRequireSasl=true
    quorum.auth.learner.loginContext=QuorumLearner 6
    quorum.auth.server.loginContext=QuorumServer
    quorum.auth.kerberos.servicePrincipal=zookeeper/_HOST 7
    quorum.cnxn.threads.size=20
    1
    以毫秒为单位控制登录续订的频率,可以调整以适应票据续订间隔。默认值为一小时。
    2
    指定主机名是否用作登录主体名称的一部分。如果将单个 keytab 用于集群中的所有节点,则设为 true。但是,建议为每个代理主机生成单独的 keytab 和完全限定主体,以进行故障排除。
    3
    控制域名称是否从 Kerberos 协商的主体名称中分离。建议将此设置设置为 false
    4
    为 ZooKeeper 服务器和客户端启用 SASL 身份验证机制。
    5
    RequireSasl 属性控制制裁事件是否需要 SASL 身份验证,如 master 选举机制。
    6
    loginContext 属性标识用于对指定组件进行身份验证的 JAAS 配置中登录上下文的名称。loginContext 名称与 opt/kafka/config/jaas.conf 文件中相关部分的名称对应。
    7
    控制用于组成用于识别的主体名称的命名惯例。占位符 _HOST 会在运行时自动解析为 server.1 属性定义的主机名。
  3. 使用 JVM 参数启动 ZooKeeper,以指定 Kerberos 登录配置:

    su - kafka
    export EXTRA_ARGS="-Djava.security.krb5.conf=/etc/krb5.conf -Djava.security.auth.login.config=/opt/kafka/config/jaas.conf"; /opt/kafka/bin/zookeeper-server-start.sh -daemon /opt/kafka/config/zookeeper.properties

    如果您不使用默认服务名称(zookeeper),请使用 -Dzookeeper.sasl.client.username=NAME 参数添加名称。

    注意

    如果您使用 /etc/krb5.conf 位置,则不需要在启动 ZooKeeper, Kafka, 或 Kafka 生成者和消费者时不需要指定 -Djava.security.krb5.conf=/etc/krb5.conf

将 Kafka 代理服务器配置为使用 Kerberos 登录

使用之前为 kafka 创建的 user principals 和 keytabs,将 Kafka 配置为使用 Kerberos 密钥分发中心(KDC)进行身份验证。

  1. 使用以下元素修改 opt/kafka/config/jaas.conf 文件:

    KafkaServer {
        com.sun.security.auth.module.Krb5LoginModule required
        useKeyTab=true
        storeKey=true
        keyTab="/opt/kafka/krb5/kafka-node1.keytab"
        principal="kafka/node1.example.redhat.com@EXAMPLE.REDHAT.COM";
    };
    KafkaClient {
        com.sun.security.auth.module.Krb5LoginModule required debug=true
        useKeyTab=true
        storeKey=true
        useTicketCache=false
        keyTab="/opt/kafka/krb5/kafka-node1.keytab"
        principal="kafka/node1.example.redhat.com@EXAMPLE.REDHAT.COM";
    };
  2. 通过修改 config/server.properties 文件中的监听程序配置 Kafka 集群中的每个代理,以便监听器使用 SASL/GSSAPI 登录。

    将 SASL 协议添加到监听器的安全协议映射中,并删除所有不需要的协议。

    例如:

    # ...
    broker.id=0
    # ...
    listeners=SECURE://:9092,REPLICATION://:9094 1
    inter.broker.listener.name=REPLICATION
    # ...
    listener.security.protocol.map=SECURE:SASL_PLAINTEXT,REPLICATION:SASL_PLAINTEXT 2
    # ..
    sasl.enabled.mechanisms=GSSAPI 3
    sasl.mechanism.inter.broker.protocol=GSSAPI 4
    sasl.kerberos.service.name=kafka 5
    ...
    1
    配置了两个监听程序: 一个安全监听程序,用于与客户端的通用通信(支持 TLS 进行通讯),以及用于内部代理通信的复制监听程序。
    2
    对于启用了 TLS 的监听程序,协议名称为 SASL_PLAINTEXT。对于启用了 TLS 的连接器,协议名称为 SASL_PLAINTEXT。如果不需要 SSL,您可以删除 ssl.* 属性。
    3
    Kerberos 验证的 SASL 机制是 GSSAPI
    4
    用于内部代理通信的 Kerberos 身份验证。
    5
    用于指定用于身份验证的服务的名称,将其与可能也使用相同的 Kerberos 配置的其他服务区分开。
  3. 启动 Kafka 代理,使用 JVM 参数来指定 Kerberos 登录配置:

    su - kafka
    export KAFKA_OPTS="-Djava.security.krb5.conf=/etc/krb5.conf -Djava.security.auth.login.config=/opt/kafka/config/jaas.conf"; /opt/kafka/bin/kafka-server-start.sh -daemon /opt/kafka/config/server.properties

    如果代理和 ZooKeeper 集群之前已经配置并使用基于非 Kerberos 的身份验证系统,则可以启动 ZooKeeper 和 broker 集群,并检查日志中是否存在配置错误。

    启动代理和 Zookeeper 实例后,集群现在被配置为 Kerberos 身份验证。

配置 Kafka producer 和消费者客户端以使用 Kerberos 身份验证

使用之前为 producer1consumer1 创建的用户主体和 keytabs 配置 Kafka producer 和 使用者客户端,以使用 Kerberos 密钥分发中心(KDC)进行身份验证。

  1. 将 Kerberos 配置添加到制作者或消费者配置文件中。

    例如:

    /opt/kafka/config/producer.properties

    # ...
    sasl.mechanism=GSSAPI 1
    security.protocol=SASL_PLAINTEXT 2
    sasl.kerberos.service.name=kafka 3
    sasl.jaas.config=com.sun.security.auth.module.Krb5LoginModule required \ 4
        useKeyTab=true  \
        useTicketCache=false \
        storeKey=true  \
        keyTab="/opt/kafka/krb5/producer1.keytab" \
        principal="producer1/node1.example.redhat.com@EXAMPLE.REDHAT.COM";
    # ...

    1
    配置 Kerberos (GSSAPI)身份验证。
    2
    Kerberos 使用 SASL 纯文本(用户名/密码)安全协议。
    3
    在 Kerberos KDC 中配置的 Kafka 的服务主体(用户)。
    4
    使用 jaas.conf 中定义的相同属性配置 JAAS。

    /opt/kafka/config/consumer.properties

    # ...
    sasl.mechanism=GSSAPI
    security.protocol=SASL_PLAINTEXT
    sasl.kerberos.service.name=kafka
    sasl.jaas.config=com.sun.security.auth.module.Krb5LoginModule required \
        useKeyTab=true  \
        useTicketCache=false \
        storeKey=true  \
        keyTab="/opt/kafka/krb5/consumer1.keytab" \
        principal="consumer1/node1.example.redhat.com@EXAMPLE.REDHAT.COM";
    # ...

  2. 运行客户端以验证您可以从 Kafka 代理发送和接收信息。

    制作者客户端:

    export KAFKA_HEAP_OPTS="-Djava.security.krb5.conf=/etc/krb5.conf -Dsun.security.krb5.debug=true"; /opt/kafka/bin/kafka-console-producer.sh --producer.config /opt/kafka/config/producer.properties  --topic topic1 --bootstrap-server node1.example.redhat.com:9094

    消费者客户端:

    export KAFKA_HEAP_OPTS="-Djava.security.krb5.conf=/etc/krb5.conf -Dsun.security.krb5.debug=true"; /opt/kafka/bin/kafka-console-consumer.sh --consumer.config /opt/kafka/config/consumer.properties  --topic topic1 --bootstrap-server node1.example.redhat.com:9094

第 17 章 设置分布式追踪

分布式追踪允许您跟踪分布式系统中应用程序之间的事务进度。在微服务架构中,追踪跟踪服务间的事务进度。跟踪数据可用于监控应用程序性能和调查目标系统和最终用户应用的问题。

在 AMQ Streams 中,追踪有助于对消息的端到端跟踪:从源系统到 Kafka,然后从 Kafka 到目标系统和应用程序。它补充了可用于在 JMX 指标 以及组件日志记录器中查看的指标。

以下 Kafka 组件内置了对追踪的支持:

  • Kafka Connect
  • MirrorMaker
  • MirrorMaker 2
  • AMQ Streams Kafka Bridge

Kafka 代理不支持追踪。

您可以在组件的属性文件中添加追踪配置。

要启用追踪,您需要设置环境变量并将追踪系统库添加到 Kafka classpath 中。对于 Jaeger 追踪,您可以为以下系统添加追踪工件:

  • OpenTelemetry 与 Jaeger Exporter
  • Jaeger 的 OpenTracing
注意

对 OpenTracing 的支持已弃用。Jaeger 客户端现已停用,OpenTracing 项目存档。因此,我们不能保证其对将来的 Kafka 版本的支持。

要在 Kafka producer、消费者和 Kafka Streams API 应用程序中启用追踪,您可以 检测 应用程序代码。在检测程序时,客户端会生成 trace 数据;例如,当生成消息或向日志写入偏移时。

注意

为 AMQ Streams 以外的应用程序和系统设置追踪不在此内容范围内。

17.1. 流程概述

要为 AMQ Streams 设置追踪,请按照以下步骤执行:

注意

有关为 Kafka Bridge 启用追踪的详情,请参考使用 AMQ Streams Kafka Bridge

17.2. 追踪选项

在 Jaeger 追踪系统中使用 OpenTelemetry 或 OpenTracing (已弃用)。

OpenTelemetry 和 OpenTracing 提供独立于追踪或监控系统的 API 规格。

您可以使用 API 检测应用程序代码以进行追踪。

  • 检测的应用程序会为跨分布式系统的单个请求生成 trace
  • trace 由定义特定工作单元的 span 组成。

Jaeger 是基于微服务的分布式系统的追踪系统。

  • Jaeger 实现追踪 API,并为工具提供客户端库。
  • Jaeger 用户界面允许您查询、过滤和分析 trace 数据。

Jaeger 用户界面显示一个简单的查询

The Jaeger user interface showing a simple query

17.3. 用于追踪的环境变量

当您为 Kafka 组件启用追踪或为 Kafka 客户端初始化 tracer 时,请使用环境变量。

追踪环境变量可能会改变。有关最新信息,请参阅 OpenTelemetry 文档OpenTracing 文档

下表描述了设置 tracer 的关键环境变量。

表 17.1. OpenTelemetry 环境变量

属性必需Description

OTEL_SERVICE_NAME

OpenTelemetry 的 Jaeger tracing 服务的名称。

OTEL_EXPORTER_JAEGER_ENDPOINT

用于追踪的导出器。

OTEL_TRACES_EXPORTER

用于追踪的导出器。默认设置为 otlp。如果使用 Jaeger 追踪,则需要将此环境变量设置为 jaeger。如果您使用另一个追踪实施,请指定使用的导出器

表 17.2. OpenTracing 环境变量

属性必需Description

JAEGER_SERVICE_NAME

Jaeger tracer 服务的名称。

JAEGER_AGENT_HOST

通过用户数据报协议(UDP)与 jaeger-agent 通信的主机名。

JAEGER_AGENT_PORT

用于通过 UDP 与 jaeger-agent 通信的端口。

17.4. 为 Kafka Connect 启用追踪

使用配置属性为 Kafka Connect 启用分布式追踪。只有 Kafka Connect 本身生成和使用的消息才会被跟踪。要跟踪 Kafka Connect 和外部系统之间发送的消息,您必须在连接器中为这些系统配置追踪。

您可以启用使用 OpenTelemetry 或 OpenTracing 的追踪。

流程

  1. 将追踪工件添加到 opt/kafka/libs 目录中。
  2. 在相关的 Kafka Connect 配置文件中配置制作者和消费者追踪。

    • 如果您以独立模式运行 Kafka 连接,请编辑 /opt/kafka/config/connect-standalone.properties 文件。
    • 如果您以分布式模式运行 Kafka Connect,请编辑 /opt/kafka/config/connect-distributed.properties 文件。

    在配置文件中添加以下追踪拦截器属性:

    OpenTelemetry 的属性

    producer.interceptor.classes=io.opentelemetry.instrumentation.kafkaclients.TracingProducerInterceptor
    consumer.interceptor.classes=io.opentelemetry.instrumentation.kafkaclients.TracingConsumerInterceptor

    OpenTracing 的属性

    producer.interceptor.classes=io.opentracing.contrib.kafka.TracingProducerInterceptor
    consumer.interceptor.classes=io.opentracing.contrib.kafka.TracingConsumerInterceptor

    启用追踪后,您可以在运行 Kafka Connect 脚本时初始化追踪。

  3. 保存配置文件。
  4. 设置用于追踪 的环境变量
  5. 使用配置文件作为参数(以及任何连接器属性)在独立或分布式模式下启动 Kafka 连接:

    在独立模式中运行 Kafka 连接

    su - kafka
    /opt/kafka/bin/connect-standalone.sh \
    /opt/kafka/config/connect-standalone.properties \
    connector1.properties \
    [connector2.properties ...]

    在分布式模式下运行 Kafka 连接

    su - kafka
    /opt/kafka/bin/connect-distributed.sh /opt/kafka/config/connect-distributed.properties

    Kafka Connect 的内部使用者和制作者现在被启用以进行追踪。

17.5. 为 MirrorMaker 2 启用追踪

通过在 MirrorMaker 2 属性文件中定义 Interceptor 属性来启用 MirrorMaker 2 的分布式追踪。Kafka 集群间追踪消息。跟踪数据记录消息进入和离开 MirrorMaker 2 组件。

您可以启用使用 OpenTelemetry 或 OpenTracing 的追踪。

流程

  1. 将追踪工件添加到 opt/kafka/libs 目录中。
  2. opt/kafka/config/connect-mirror-maker.properties 文件中配置制作者和消费者追踪。

    在配置文件中添加以下追踪拦截器属性:

    OpenTelemetry 的属性

    header.converter=org.apache.kafka.connect.converters.ByteArrayConverter
    producer.interceptor.classes=io.opentelemetry.instrumentation.kafkaclients.TracingProducerInterceptor
    consumer.interceptor.classes=io.opentelemetry.instrumentation.kafkaclients.TracingConsumerInterceptor

    OpenTracing 的属性

    header.converter=org.apache.kafka.connect.converters.ByteArrayConverter
    producer.interceptor.classes=io.opentracing.contrib.kafka.TracingProducerInterceptor
    consumer.interceptor.classes=io.opentracing.contrib.kafka.TracingConsumerInterceptor

    ByteArrayConverter 会阻止 Kafka Connect 将消息标头(包含追踪 ID)转换为 base64 编码。这样可确保在源和目标集群中都有相同的信息。

    启用追踪后,您可以在运行 Kafka MirrorMaker 2 脚本时初始化追踪。

  3. 保存配置文件。
  4. 设置用于追踪 的环境变量
  5. 使用制作者和消费者配置文件作为参数启动 MirrorMaker 2:

    su - kafka
    /opt/kafka/bin/connect-mirror-maker.sh \
    /opt/kafka/config/connect-mirror-maker.properties

    MirrorMaker 2 的内部消费者和制作者现在被启用以进行追踪。

17.6. 为 MirrorMaker 启用追踪

通过将 Interceptor 属性作为使用者和制作者配置参数传递,为 MirrorMaker 启用分布式追踪。消息从源集群追踪到目标集群。跟踪数据记录消息进入和离开 MirrorMaker 组件。

您可以启用使用 OpenTelemetry 或 OpenTracing 的追踪。

流程

  1. 将追踪工件添加到 opt/kafka/libs 目录中。
  2. /opt/kafka/config/producer.properties 文件中配置生产者追踪。

    添加以下追踪拦截器属性:

    OpenTelemetry 的 producer 属性

    producer.interceptor.classes=io.opentelemetry.instrumentation.kafkaclients.TracingProducerInterceptor

    OpenTracing 的制作者属性

    producer.interceptor.classes=io.opentracing.contrib.kafka.TracingProducerInterceptor

  3. 保存配置文件。
  4. /opt/kafka/config/consumer.properties 文件中配置消费者追踪。

    添加以下追踪拦截器属性:

    OpenTelemetry 的 consumer 属性

    consumer.interceptor.classes=io.opentelemetry.instrumentation.kafkaclients.TracingConsumerInterceptor

    OpenTracing 的使用者属性

    consumer.interceptor.classes=io.opentracing.contrib.kafka.TracingConsumerInterceptor

    启用追踪后,您可以在运行 Kafka MirrorMaker 脚本时初始化追踪。

  5. 保存配置文件。
  6. 设置用于追踪 的环境变量
  7. 使用制作者和消费者配置文件作为参数启动 MirrorMaker:

    su - kafka
    /opt/kafka/bin/kafka-mirror-maker.sh \
    --producer.config /opt/kafka/config/producer.properties \
    --consumer.config /opt/kafka/config/consumer.properties \
    --num.streams=2

    MirrorMaker 的内部使用者和制作者现已启用以进行追踪。

17.7. 为 Kafka 客户端初始化追踪

初始化 tracer,然后检测您的客户端应用程序以进行分布式追踪。您可以检测 Kafka producer 和使用者客户端,以及 Kafka Streams API 应用程序。您可以为 OpenTracing 或 OpenTelemetry 初始化 tracer。

使用一组 追踪环境变量 配置和初始化 tracer。

流程

在每个客户端应用程序中,为 tracer 添加依赖项:

  1. 将 Maven 依赖项添加到客户端应用程序的 pom.xml 文件中:

    OpenTelemetry 的依赖项

    <dependency>
        <groupId>io.opentelemetry</groupId>
        <artifactId>opentelemetry-sdk-extension-autoconfigure</artifactId>
        <version>1.19.0.redhat-00002</version>
    </dependency>
    <dependency>
      <groupId>io.opentelemetry.instrumentation</groupId>
      <artifactId>opentelemetry-kafka-clients-{OpenTelemetryKafkaClient}</artifactId>
      <version>1.19.0.redhat-00002</version>
    </dependency>
    <dependency>
      <groupId>io.opentelemetry</groupId>
      <artifactId>opentelemetry-exporter-otlp</artifactId>
      <version>1.19.0.redhat-00002</version>
    </dependency>

    OpenTracing 的依赖项

    <dependency>
        <groupId>io.jaegertracing</groupId>
        <artifactId>jaeger-client</artifactId>
        <version>1.8.1.redhat-00002</version>
    </dependency>
    <dependency>
      <groupId>io.opentracing.contrib</groupId>
      <artifactId>opentracing-kafka-client</artifactId>
      <version>0.1.15.redhat-00006</version>
    </dependency>

  2. 使用追踪环境变量定义 tracer 的配置。
  3. 创建一个 tracer,它使用环境变量初始化:

    为 OpenTelemetry 创建 tracer

    OpenTelemetry ot = GlobalOpenTelemetry.get();

    为 OpenTracing 创建 tracer

    Tracer tracer = Configuration.fromEnv().getTracer();

  4. 将 tracer 注册为全局 tracer:

    GlobalTracer.register(tracer);
  5. 检测您的客户端:

17.8. 检测用于追踪的生产者和消费者

检测应用程序代码,以在 Kafka 生成者和消费者中启用追踪。使用 decorator 模式或拦截器检测您的 Java 生成者和消费者应用程序代码以进行追踪。然后,您可以在生成或从主题检索信息时记录 trace。

OpenTelemetry 和 OpenTracing 检测项目提供支持生产者和消费者的类。

decorator 检测
对于 decorator 检测,请创建一个修改后的制作者或消费者实例以进行追踪。decorator 检测在 OpenTelemetry 和 OpenTracing 中有所不同。
拦截器检测
对于拦截器工具,请在消费者或制作者配置中添加追踪功能。OpenTelemetry 和 OpenTracing 的拦截器工具是相同的。

先决条件

  • 您已为 客户端初始化了追踪

    您可以通过在项目中添加追踪 JAR 作为依赖项来启用生成者和消费者应用中的检测。

流程

在每个制作者和消费者应用的应用程序代码中执行这些步骤。使用 decorator 模式或拦截器(拦截器)检测您的客户端应用程序代码。

  • 要使用 decorator 模式,请创建一个修改后的制作者或消费者实例来发送或接收消息。

    您传递了原始 KafkaProducerKafkaConsumer 类。

    OpenTelemetry 的 decorator 检测示例

    // Producer instance
    Producer < String, String > op = new KafkaProducer < > (
        configs,
        new StringSerializer(),
        new StringSerializer()
        );
        Producer < String, String > producer = tracing.wrap(op);
    KafkaTracing tracing = KafkaTracing.create(GlobalOpenTelemetry.get());
    producer.send(...);
    
    //consumer instance
    Consumer<String, String> oc = new KafkaConsumer<>(
        configs,
        new StringDeserializer(),
        new StringDeserializer()
        );
        Consumer<String, String> consumer = tracing.wrap(oc);
    consumer.subscribe(Collections.singleton("mytopic"));
    ConsumerRecords<Integer, String> records = consumer.poll(1000);
    ConsumerRecord<Integer, String> record = ...
    SpanContext spanContext = TracingKafkaUtils.extractSpanContext(record.headers(), tracer);

    OpenTracing 的 decorator 检测示例

    //producer instance
    KafkaProducer<Integer, String> producer = new KafkaProducer<>(senderProps);
    TracingKafkaProducer<Integer, String> tracingProducer = new TracingKafkaProducer<>(producer, tracer);
    TracingKafkaProducer.send(...)
    
    //consumer instance
    KafkaConsumer<Integer, String> consumer = new KafkaConsumer<>(consumerProps);
    TracingKafkaConsumer<Integer, String> tracingConsumer = new TracingKafkaConsumer<>(consumer, tracer);
    tracingConsumer.subscribe(Collections.singletonList("mytopic"));
    ConsumerRecords<Integer, String> records = tracingConsumer.poll(1000);
    ConsumerRecord<Integer, String> record = ...
    SpanContext spanContext = TracingKafkaUtils.extractSpanContext(record.headers(), tracer);

  • 要使用拦截器,请在制作者或消费者配置中设置拦截器类。

    您以通常的方式使用 KafkaProducerKafkaConsumer 类。TracingProducerInterceptorTracingConsumerInterceptor interceptor 类负责追踪功能。

    使用拦截器的制作者配置示例

    senderProps.put(ProducerConfig.INTERCEPTOR_CLASSES_CONFIG,
        TracingProducerInterceptor.class.getName());
    
    KafkaProducer<Integer, String> producer = new KafkaProducer<>(senderProps);
    producer.send(...);

    使用拦截器的消费者配置示例

    consumerProps.put(ConsumerConfig.INTERCEPTOR_CLASSES_CONFIG,
        TracingConsumerInterceptor.class.getName());
    
    KafkaConsumer<Integer, String> consumer = new KafkaConsumer<>(consumerProps);
    consumer.subscribe(Collections.singletonList("messages"));
    ConsumerRecords<Integer, String> records = consumer.poll(1000);
    ConsumerRecord<Integer, String> record = ...
    SpanContext spanContext = TracingKafkaUtils.extractSpanContext(record.headers(), tracer);

17.9. 检测用于追踪的 Kafka Streams 应用程序

检测应用程序代码,以在 Kafka Streams API 应用程序中启用追踪。使用 decorator 模式或拦截器检测 Kafka Streams API 应用程序以进行追踪。然后,您可以在生成或从主题检索信息时记录 trace。

decorator 检测
对于 decorator 检测,请创建一个修改后的 Kafka Streams 实例以进行追踪。OpenTracing 检测项目提供了一个 TracingKafkaClientSupplier 类,它支持 Kafka Streams 的检测。您可以创建一个 TracingKafkaClientSupplier 供应商接口的嵌套实例,它为 Kafka Streams 提供追踪工具。对于 OpenTelemetry,该过程相同,但您需要创建自定义 TracingKafkaClientSupplier 类来提供支持。
拦截器检测
对于拦截器工具,在 Kafka Streams producer 和 consumer 配置中添加追踪功能。

先决条件

  • 您已为 客户端初始化了追踪

    您可以通过在项目中添加追踪 JAR 作为依赖项来启用 Kafka Streams 应用程序中的检测。

  • 要使用 OpenTelemetry 检测 Kafka Streams,您需要编写自定义 TracingKafkaClientSupplier
  • 自定义 TracingKafkaClientSupplier 可以扩展 Kafka 的 DefaultKafkaClientSupplier,覆盖生成者和消费者创建方法,将实例嵌套与遥测相关的代码。

    自定义 TracingKafkaClientSupplier 示例

    private class TracingKafkaClientSupplier extends DefaultKafkaClientSupplier {
        @Override
        public Producer<byte[], byte[]> getProducer(Map<String, Object> config) {
            KafkaTelemetry telemetry = KafkaTelemetry.create(GlobalOpenTelemetry.get());
            return telemetry.wrap(super.getProducer(config));
        }
    
        @Override
        public Consumer<byte[], byte[]> getConsumer(Map<String, Object> config) {
            KafkaTelemetry telemetry = KafkaTelemetry.create(GlobalOpenTelemetry.get());
            return telemetry.wrap(super.getConsumer(config));
        }
    
        @Override
        public Consumer<byte[], byte[]> getRestoreConsumer(Map<String, Object> config) {
            return this.getConsumer(config);
        }
    
        @Override
        public Consumer<byte[], byte[]> getGlobalConsumer(Map<String, Object> config) {
            return this.getConsumer(config);
        }
    }

流程

为每个 Kafka Streams API 应用程序执行这些步骤。

  • 要使用 decorator 模式,请创建一个 TracingKafkaClientSupplier 供应商接口的实例,然后向 KafkaStreams 提供供应商接口。

    decorator 检测示例

    KafkaClientSupplier supplier = new TracingKafkaClientSupplier(tracer);
    KafkaStreams streams = new KafkaStreams(builder.build(), new StreamsConfig(config), supplier);
    streams.start();

  • 要使用拦截器,请在 Kafka Streams producer 和消费者配置中设置拦截器类。

    TracingProducerInterceptorTracingConsumerInterceptor interceptor 类负责追踪功能。

    使用拦截器的制作者和消费者配置示例

    props.put(StreamsConfig.PRODUCER_PREFIX + ProducerConfig.INTERCEPTOR_CLASSES_CONFIG, TracingProducerInterceptor.class.getName());
    props.put(StreamsConfig.CONSUMER_PREFIX + ConsumerConfig.INTERCEPTOR_CLASSES_CONFIG, TracingConsumerInterceptor.class.getName());

17.10. 使用 OpenTelemetry 指定追踪系统

您可以指定 OpenTelemetry 支持的其他追踪系统,而不是默认的 Jaeger 系统。

如果要将另一个追踪系统与 OpenTelemetry 搭配使用,请执行以下操作:

  1. 将追踪系统的库添加到 Kafka classpath 中。
  2. 将追踪系统的名称添加为额外的导出器环境变量。

    如果不使用 Jaeger 时,额外的环境变量

    OTEL_SERVICE_NAME=my-tracing-service
    OTEL_TRACES_EXPORTER=zipkin 1
    OTEL_EXPORTER_ZIPKIN_ENDPOINT=http://localhost:9411/api/v2/spans 2

    1
    追踪系统的名称。在本例中,指定了 Zipkin。
    2
    侦听 span 的特定所选导出器的端点。在本例中,指定了 Zipkin 端点。

17.11. 自定义范围名称

追踪 span 是 Jaeger 中的逻辑工作单元,包括操作名称、开始时间和持续时间。span 具有内置名称,但您可以在使用的 Kafka 客户端检测中指定自定义范围名称。

指定自定义范围名称是可选的,只有在生成者和消费者客户端检测Kafka Streams 检测中使用 decorator 模式时才适用。

17.11.1. 为 OpenTelemetry 指定范围名称

无法使用 OpenTelemetry 直接指定自定义范围名称。相反,您可以通过向客户端应用程序添加代码来提取额外的标签和属性来检索范围名称。

提取属性的代码示例

//Defines attribute extraction for a producer
private static class ProducerAttribExtractor implements AttributesExtractor < ProducerRecord < ? , ? > , Void > {
    @Override
    public void onStart(AttributesBuilder attributes, ProducerRecord < ? , ? > producerRecord) {
        set(attributes, AttributeKey.stringKey("prod_start"), "prod1");
    }
    @Override
    public void onEnd(AttributesBuilder attributes, ProducerRecord < ? , ? > producerRecord, @Nullable Void unused, @Nullable Throwable error) {
        set(attributes, AttributeKey.stringKey("prod_end"), "prod2");
    }
}
//Defines attribute extraction for a consumer
private static class ConsumerAttribExtractor implements AttributesExtractor < ConsumerRecord < ? , ? > , Void > {
    @Override
    public void onStart(AttributesBuilder attributes, ConsumerRecord < ? , ? > producerRecord) {
        set(attributes, AttributeKey.stringKey("con_start"), "con1");
    }
    @Override
    public void onEnd(AttributesBuilder attributes, ConsumerRecord < ? , ? > producerRecord, @Nullable Void unused, @Nullable Throwable error) {
        set(attributes, AttributeKey.stringKey("con_end"), "con2");
    }
}
//Extracts the attributes
public static void main(String[] args) throws Exception {
        Map < String, Object > configs = new HashMap < > (Collections.singletonMap(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092"));
        System.setProperty("otel.traces.exporter", "jaeger");
        System.setProperty("otel.service.name", "myapp1");
        KafkaTracing tracing = KafkaTracing.newBuilder(GlobalOpenTelemetry.get())
            .addProducerAttributesExtractors(new ProducerAttribExtractor())
            .addConsumerAttributesExtractors(new ConsumerAttribExtractor())
            .build();

17.11.2. 为 OpenTracing 指定范围名称

要为 OpenTracing 指定自定义范围名称,请在检测生产者和消费者时将 BiFunction 对象作为参数传递。

有关内置名称和指定自定义范围名称以检测客户端应用代码的更多信息,请参阅 OpenTracing Apache Kafka 客户端检测

第 18 章 使用 Kafka Exporter

Kafka Exporter 是一个开源项目,用于增强对 Apache Kafka 代理和客户端的监控。

Kafka Exporter 由 AMQ Streams 提供,用于与 Kafka 集群部署,以便从与偏移、消费者组、消费者和主题相关的 Kafka 代理提取其他指标数据。

例如,指标数据用于帮助识别较慢的用户。

滞后数据作为 Prometheus 指标公开,然后可在 Grafana 中显示以进行分析。

如果您已经使用 Prometheus 和 Grafana 监控内置 Kafka 指标,您可以将 Prometheus 配置为提取 Kafka Exporter Prometheus 端点。

Kafka 通过 JMX 来公开指标,然后可以作为 Prometheus 指标导出。如需更多信息,请参阅使用 JMX 监控集群

18.1. 消费者滞后

消费者滞后表示消息的速度与消息的消耗的差别。具体来说,给定消费者组的消费者滞后指示分区中最后一个消息之间的延迟,以及当前由该消费者获取的消息之间的延迟。lag 反映了与分区日志结束相关的消费者偏移的位置。

这种差异有时被称为生成偏移和消费者偏移之间的 delta,即 Kafka 代理主题分区中的读写位置。

假设主题流 100 个消息。在制作者偏移(主题分区头)和最后一个偏移之间发生 1000 个消息,使用者读取的最后偏移时间为 10 秒的延迟。

监控消费者的重要性

对于依赖于实时数据的处理的应用程序,监控消费者来判断其是否不会变得太大。整个过程越好,流程从实时处理目标中得到的增长。

例如,消费者滞后可能是消耗太多的旧数据(这些数据尚未被清除)或出现计划外的关闭。

减少消费者滞后

减少滞后的典型操作包括:

  • 通过添加新消费者来扩展消费者组
  • 增加保留时间以便消息保留在主题中
  • 添加更多磁盘容量以增加消息缓冲

减少消费者滞后的操作取决于底层基础架构和 AMQ Streams 的用例。例如,分发的消费者不太可能从其磁盘缓存中获取请求的服务从代理服务。在某些情况下,在消费者发现前,可以接受自动丢弃消息。

18.2. Kafka Exporter 警报规则示例

特定于 Kafka Exporter 的警报通知规则示例如下:

UnderReplicatedPartition
警告一个主题被复制,代理没有复制足够的分区。如果主题有一个或多个重复分区,默认配置是警报。该警报可能会表示 Kafka 实例已停机或 Kafka 集群过载。可能需要重启 Kafka 代理来重启复制过程。
TooLargeConsumerGroupLag
警告消费者组中的滞后对于特定的主题分区太大。默认配置是 1000 个记录。大型滞后可能会表示消费者太慢,并位于生产者后。
NoMessageForTooLong
警告一个警报,以警告主题在一段时间内没有收到消息。时间的默认配置为 10 分钟。延迟可能是配置问题,阻止生成者向主题发布消息。

您可以根据具体需要调整警报规则。

其他资源

有关设置警报规则的更多信息,请参阅 Prometheus 文档中的配置。

18.3. Kafka Exporter 指标

Kafka Exporter 会公开信息,作为 Grafana 中演示的 Prometheus 指标。

Kafka Exporter 为代理、主题和消费者组公开指标数据。

表 18.1. 代理指标输出

Name信息

kafka_brokers

Kafka 集群中的代理数

表 18.2. 主题指标输出

Name信息

kafka_topic_partitions

主题的分区数

kafka_topic_partition_current_offset

代理的当前主题分区偏移

kafka_topic_partition_oldest_offset

代理的最旧的主题分区偏移

kafka_topic_partition_in_sync_replica

主题分区的同步副本数

kafka_topic_partition_leader

主题分区的领导代理 ID

kafka_topic_partition_leader_is_preferred

如果主题分区使用首选代理,则显示 1

kafka_topic_partition_replicas

本主题分区的副本数

kafka_topic_partition_under_replicated_partition

如果主题分区复制不足,显示 1

表 18.3. 消费者组指标输出

Name信息

kafka_consumergroup_current_offset

消费者组的当前主题分区偏移

kafka_consumergroup_lag

当前在主题分区中的消费者组滞后

18.4. 运行 Kafka Exporter

运行 Kafka Exporter,以公开 Prometheus 指标以便在 Grafana 仪表板中进行演示。

下载并安装 Kafka Exporter 软件包,以便将 Kafka Exporter 与 AMQ Streams 搭配使用。您需要一个 AMQ Streams 订阅才能下载并安装软件包。

此流程假设您已经访问 Grafana 用户界面,并添加了 Prometheus 作为数据源。

流程

  1. 安装 Kafka Exporter 软件包:

    dnf install kafka_exporter
  2. 验证软件包是否已安装:

    dnf info kafka_exporter
  3. 使用适当的配置参数值运行 Kafka Exporter:

    kafka_exporter --kafka.server=<kafka_bootstrap_address>:9092 --kafka.version=3.5.0  --<my_other_parameters>

    参数需要双yphen 规范,如 --kafka.server

    表 18.4. Kafka Exporter 配置参数

    选项描述默认

    kafka.server

    Kafka 服务器的主机/发布地址。

    kafka:9092

    kafka.version

    Kafka 代理版本。

    1.0.0

    group.filter

    指定指标中包含的消费者组的正则表达式。

    IANA (all)

    topic.filter

    指定指标中包含的主题的正则表达式。

    IANA (all)

    sasl.<parameter>

    使用 SASL/PLAIN 身份验证(使用用户名和密码)启用和连接到 Kafka 集群的参数。

    false

    tls.<parameter>

    启用使用 TLS 身份验证连接到 Kafka 集群的参数,以及可选的证书和密钥。

    false

    web.listen-address

    用于公开指标的端口地址。

    :9308

    web.telemetry-path

    公开指标的路径。

    /metrics

    log.level

    日志记录配置,以记录具有给定严重性(debug、info、warn、error、fatal)或以上的消息。

    info

    log.enable-sarama

    启用 Sarama 日志记录的布尔值,这是 Kafka Exporter 使用的 Go 客户端库。

    false

    legacy.partitions

    布尔值,以启用从非活动主题分区以及活跃的分区中获取指标。如果您希望 Kafka Exporter 返回不活跃分区的指标,设置为 true

    false

    您可以使用 kafka_exporter --help 来了解有关属性的信息。

  4. 配置 Prometheus 以监控 Kafka Exporter 指标。

    有关配置 Prometheus 的更多信息,请参阅 Prometheus 文档

  5. 启用 Grafana 以显示 Prometheus 公开的 Kafka Exporter 指标数据。

    如需更多信息,请参阅在 Grafana 中显示 Kafka 导出器指标

更新 Kafka Exporter

在 AMQ Streams 安装中使用最新版本的 Kafka Exporter。

要检查更新,请使用:

dnf check-update

要更新 Kafka Exporter,请使用:

dnf update kafka_exporter

18.5. 在 Grafana 中显示 Kafka Exporter 指标

使用 Kafka Exporter Prometheus 指标作为数据源,您可以创建一个 Grafana chart 的仪表板。

例如,从指标中创建以下 Grafana chart:

  • 每秒的消息(来自主题)
  • 每分钟的消息(来自主题)
  • 消费者组滞后
  • 每分钟消耗的消息(按消费者组)

当收集一段时间的指标数据时,会填充 Kafka Exporter chart。

使用 Grafana chart 分析滞后,检查操作是否减少对受影响的消费者组的影响。例如,如果对 Kafka 代理进行了调整以减少滞后,仪表板将显示 Lag by consumer group 图表下降,Messages consumed per minute 图表增加。

第 19 章 升级 AMQ Streams 和 Kafka

在不需要停机的情况下升级 Kafka 集群。Red Hat Enterprise Linux 的 AMQ Streams 发行版本支持一个 Apache Kafka 版本。安装最新版本的 AMQ Streams 时,您可以升级到最新的 Kafka 版本。

19.1. 升级先决条件

在开始升级过程前,请确定您熟悉 Red Hat Enterprise Linux 发行注记上的 AMQ Streams 2.5 中所述的升级更改。

注意

有关如何升级到该版本的信息,请参阅支持 AMQ Streams 特定版本的文档。

19.2. Kafka 版本

Kafka 的日志消息格式版本和 inter-broker 协议版本分别指定日志格式版本,日志格式版本附加到消息以及集群中使用的 Kafka 协议的版本。为确保使用了正确的版本,升级过程涉及对现有 Kafka 代理和客户端应用程序(使用者和生产者)进行配置更改。

下表显示了 Kafka 版本之间的区别:

表 19.1. Kafka 版本的不同

AMQ Streams 版本Kafka 版本间的代理协议版本日志消息格式版本zookeeper 版本

2.5

3.5.0

3.5

3.5

3.6.4

2.4

3.4.0

3.4

3.4

3.6.3

注意

AMQ Streams 2.5 使用 Kafka 3.5.0,但 Kafka 3.4.0 也支持进行升级。

间的代理协议版本

在 Kafka 中,用于内部代理通信的网络协议称为 inter-broker 协议。Kafka 的每个版本都有了一个内部代理协议的兼容版本。协议的次要版本通常会增加以匹配 Kafka 的次版本,如上表所示。

Kafka 资源中设置集群范围的协议版本。要更改它,您可以编辑 Kafka.spec.kafka.config 中的 inter.broker.protocol.version 属性。

日志消息格式版本

当制作者向 Kafka 代理发送消息时,消息使用特定格式进行编码。格式可以在 Kafka 发行版本间有所变化,因此消息指定了它们编码的消息格式版本。

用于设置特定消息格式版本的属性如下:

  • 主题的 message.format.version 属性
  • Kafka 代理的 log.message.format.version 属性

从 Kafka 3.0.0,消息格式版本值被假定为与 inter.broker.protocol.version 匹配,且不需要设置。这些值反映了使用的 Kafka 版本。

当升级到 Kafka 3.0.0 或更高版本时,您可以在更新 inter.broker.protocol.version 时删除这些设置。否则,请基于您要升级到的 Kafka 版本设置消息格式版本。

由在 Kafka 代理中设置的 log.message.format.version 定义的 message.format.version 的默认值。您可以通过修改其主题配置来手动设置主题的 message.format.version

19.3. 升级客户端的策略

升级 Kafka 客户端可确保它们从新版本的 Kafka 中引入的功能、修复和改进中受益。升级的客户端维护与其他升级的 Kafka 组件的兼容性。客户端的性能和稳定性也可能得到改进。

考虑升级 Kafka 客户端和服务器的最佳方法,以确保平稳过渡。所选升级策略取决于您是否先升级代理或客户端。从 Kafka 3.0 开始,您可以独立和顺序升级代理和客户端。决定升级客户端或代理首先取决于几个因素,如需要升级的应用程序数量以及可容忍的停机时间。

如果您在代理前升级客户端,一些新功能可能无法工作,因为代理尚不支持它们。但是,代理可以处理使用不同版本运行的制作者和消费者,并支持不同的日志消息版本。

当使用 Kafka 3.0 旧的 Kafka 版本时升级客户端

在 Kafka 3.0 之前,您可以使用 log.message.format.version 属性(或主题级别的 message.format.version 属性)为代理配置特定的消息格式。这允许代理支持使用过时消息格式的旧的 Kafka 客户端。否则,代理需要从旧的客户端转换信息,这会显著提高性能成本。

自 0.11 版以来,Apache Kafka Java 客户端支持最新的消息格式版本。如果所有客户端都使用最新的消息版本,您可以在升级代理时删除 log.message.format.versionmessage.format.version 覆盖。

但是,如果您仍然有使用较旧的消息格式版本的客户端,我们建议首先升级您的客户端。从消费者开始,在升级代理时,在删除 log.message.format.versionmessage.format.version 前升级制作者。这将确保所有客户端都可以支持最新的消息格式版本,并且升级过程可以平稳进行。

您可以使用此指标跟踪 Kafka 客户端名称和版本:

  • kafka.server:type=socket-server-metrics,clientSoftwareName=<name>,clientSoftwareVersion=<version>,listener=<listener>,networkProcessor=<processor>
提示

以下 Kafka 代理指标帮助监控消息 down-conversion 的性能:

  • kafka.network:type=RequestMetrics,name=MessageConversionsTimeMs,request={Produce|Fetch} 提供执行消息转换所需时间的指标。
  • kafka.server:type=BrokerTopicMetrics,name={Produce|Fetch}MessageConversionsPerSec,topic=([-.\w]+) 提供一段时间内转换的消息数量的指标。

19.4. 升级 Kafka 代理和 ZooKeeper

在主机机器上升级 Kafka 代理和 ZooKeeper 以使用 AMQ Streams 的最新版本。您可以更新安装文件,然后配置并重启所有 Kafka 代理以使用新的 inter-broker 协议版本。执行这些步骤后,使用新的 inter-broker 协议版本在 Kafka 代理间传输数据。

注意

从 Kafka 3.0.0 开始,消息格式版本值被假定为与 inter.broker.protocol.version 匹配,不需要设置。这些值反映了使用的 Kafka 版本。

先决条件

流程

对于 AMQ Streams 集群中的每个 Kafka 代理,一次一个:

  1. 从 AMQ Streams 软件下载页面 下载 AMQ Streams 存档。

    注意

    若有提示,登录到您的红帽帐户。

  2. 在命令行中,创建一个临时目录并提取 amq-streams-<version>-bin.zip 文件的内容。

    mkdir /tmp/kafka
    unzip amq-streams-<version>-bin.zip -d /tmp/kafka
  3. 如果正在运行,停止 ZooKeeper 和主机上运行的 Kafka 代理。

    /opt/kafka/bin/zookeeper-server-stop.sh
    /opt/kafka/bin/kafka-server-stop.sh
    jcmd | grep zookeeper
    jcmd | grep kafka

    如果您在多节点集群中运行 Kafka,请参阅 第 4.3 节 “执行 Kafka 代理的安全滚动重启”

  4. 从现有安装中删除 libsbin 目录:

    rm -rf /opt/kafka/libs /opt/kafka/bin
  5. 从临时目录中复制 libsbin 目录:

    cp -r /tmp/kafka/kafka_<version>/libs /opt/kafka/
    cp -r /tmp/kafka/kafka_<version>/bin /opt/kafka/
  6. 如果需要,更新 config 目录中的配置文件以反映新版本中的任何更改。
  7. 删除临时目录。

    rm -r /tmp/kafka
  8. 编辑 /opt/kafka/config/server.properties 属性文件。

    inter.broker.protocol.versionlog.message.format.version 属性设置为当前版本。

    例如,如果从 Kafka 版本 3.4.0 升级到 3.5.0,则当前版本为 3.4 :

    inter.broker.protocol.version=3.4
    log.message.format.version=3.4

    为您要从中升级的 Kafka 版本使用正确的版本(3.33.4 等)。在当前设置中保持不变 inter.broker.protocol.version,可确保代理可以在整个升级过程中继续相互通信。

    如果没有配置属性,请使用当前版本添加它们。

    如果您要从 Kafka 3.0.0 或更高版本升级,则只需要设置 inter.broker.protocol.version

  9. 重启更新的 ZooKeeper 和 Kafka 代理:

    /opt/kafka/bin/zookeeper-server-start.sh -daemon /opt/kafka/config/zookeeper.properties
    /opt/kafka/bin/kafka-server-start.sh -daemon /opt/kafka/config/server.properties

    Kafka 代理和 ZooKeeper 开始使用最新 Kafka 版本的二进制文件。

    有关在多节点集群中重启代理的详情,请参考 第 4.3 节 “执行 Kafka 代理的安全滚动重启”

  10. 验证重启的 Kafka 代理是否使用其分区副本发现。

    使用 kafka-topics.sh 工具来确保代理中包含的所有副本都同步。具体步骤请参阅 列出和描述主题

    在下一步中,更新 Kafka 代理以使用新的 inter-broker 协议版本。

    一次更新每个代理。

    警告

    完成以下步骤后无法降级 AMQ Streams。

  11. 根据您选择 升级客户端的策略,升级所有客户端应用程序以使用客户端二进制文件的新版本。
  12. /opt/kafka/config/server.properties 文件中将 inter.broker.protocol.version 属性设置为 3.5

    inter.broker.protocol.version=3.5
  13. 在命令行中,停止您修改的 Kafka 代理:

    /opt/kafka/bin/kafka-server-stop.sh
  14. 检查 Kafka 没有运行:

    jcmd | grep kafka
  15. 重启您修改的 Kafka 代理:

    /opt/kafka/bin/kafka-server-start.sh -daemon /opt/kafka/config/server.properties
  16. 检查 Kafka 是否正在运行:

    jcmd | grep kafka
  17. 如果您要从 Kafka 3.0.0 之前的版本升级,请在 /opt/kafka/config/server.properties 文件中将 log.message.format.version 属性设置为 3.5

    log.message.format.version=3.5
  18. 在命令行中,停止您修改的 Kafka 代理:

    /opt/kafka/bin/kafka-server-stop.sh
  19. 检查 Kafka 没有运行:

    jcmd | grep kafka
  20. 重启您修改的 Kafka 代理:

    /opt/kafka/bin/kafka-server-start.sh -daemon /opt/kafka/config/server.properties
  21. 检查 Kafka 是否正在运行:

    jcmd | grep kafka
  22. 验证重启的 Kafka 代理是否使用其分区副本发现。

    使用 kafka-topics.sh 工具来确保代理中包含的所有副本都同步。具体步骤请参阅 列出和描述主题

  23. 如果在升级过程中使用了它,请从 server.properties 文件中删除旧的 log.message.format.version 配置。

19.5. 升级 Kafka 组件

升级主机上的 Kafka 组件以使用 AMQ Streams 的最新版本。您可以使用 AMQ Streams 安装文件来升级以下组件:

  • Kafka Connect
  • MirrorMaker
  • Kafka Bridge (separate ZIP 文件)

先决条件

  • kafka 用户身份登录 Red Hat Enterprise Linux。
  • 您已下载了 安装文件
  • 您已在单独的主机上安装 Kafka 和其他 Kafka 组件。

    更多信息请参阅 第 3.1 节 “安装环境”

  • 您已 升级了 Kafka 和 ZooKeeper

    如果 Kafka 组件在与 Kafka 和 ZooKeeper 相同的主机上运行,您还需要升级时停止并启动 Kafka 和 ZooKeeper。

流程

对于运行 Kafka 组件实例的每个主机:

  1. 从 AMQ Streams 软件下载页面下载 AMQ Streams 或 Kafka Bridge 安装文件。

    注意

    若有提示,登录到您的红帽帐户。

  2. 在命令行中,创建一个临时目录并提取 amq-streams-<version>-bin.zip 文件的内容。

    mkdir /tmp/kafka
    unzip amq-streams-<version>-bin.zip -d /tmp/kafka

    对于 Kafka Bridge,提取 amq-streams-<version>-bridge-bin.zip 文件。

  3. 如果正在运行,停止主机上运行的 Kafka 组件。
  4. 从现有安装中删除 libsbin 目录:

    rm -rf /opt/kafka/libs /opt/kafka/bin
  5. 从临时目录中复制 libsbin 目录:

    cp -r /tmp/kafka/kafka_<version>/libs /opt/kafka/
    cp -r /tmp/kafka/kafka_<version>/bin /opt/kafka/
  6. 如果需要,更新 config 目录中的配置文件以反映新版本中的任何更改。
  7. 删除临时目录。

    rm -r /tmp/kafka
  8. 使用适当的脚本和属性文件启动 Kafka 组件。

    以独立模式启动 Kafka 连接

    /opt/kafka/bin/connect-standalone.sh \
    /opt/kafka/config/connect-standalone.properties <connector1>.properties
    [<connector2>.properties ...]

    在分布式模式中启动 Kafka 连接

    /opt/kafka/bin/connect-distributed.sh \
    /opt/kafka/config/connect-distributed.properties

    以专用模式启动 MirrorMaker 2

    /opt/kafka/bin/connect-mirror-maker.sh \
    /opt/kafka/config/connect-mirror-maker.properties

    启动 Kafka Bridge

    su - kafka
    ./bin/kafka_bridge_run.sh \
    --config-file=<path>/application.properties

  9. 验证 Kafka 组件是否正在运行,并按预期生成或消耗数据。

    在独立模式中验证 Kafka 连接正在运行

    jcmd | grep ConnectStandalone

    在分布式模式中验证 Kafka 连接正在运行

    jcmd | grep ConnectDistributed

    在专用模式中验证 MirrorMaker 2 正在运行

    jcmd | grep mirrorMaker

    通过检查日志来验证 Kafka Bridge 是否正在运行

    HTTP-Kafka Bridge started and listening on port 8080
    HTTP-Kafka Bridge bootstrap servers localhost:9092

第 20 章 使用 JMX 监控集群

收集指标对于了解 Kafka 部署的健康状况和性能至关重要。通过监控指标,您可以在问题变为关键前主动发现问题,并对资源分配和容量规划做出建议决策。如果没有指标数据,您可能会对 Kafka 部署的行为具有有限的可见性,这使得故障排除更困难和耗时。设置指标可节省长时间运行时和资源,并帮助确保 Kafka 部署的可靠性。

Kafka 代理、Kook、Kafka Connect 和 Kafka 客户端使用 Java Management Extensions (JMX)来主动公开管理信息。此信息主要由有助于监控 Kafka 集群的性能和条件的指标组成。Kafka 与其他 Java 应用程序一样,依赖于受管 Bean 或 MBeans 提供此信息来监控工具和仪表板。

JMX 在 JVM 级别运行,允许外部工具从 ZooKeeper、Kafka 代理等连接和检索管理信息。要连接到 JVM,这些工具必须在同一台机器上运行,默认与同一用户运行。

20.1. 启用 JMX 代理

使用 JVM 系统属性启用对 Kafka 组件的 JMX 监控。使用 KAFKA_JMX_OPTS 环境变量设置启用 JMX 监控所需的 JMX 系统属性。运行 Kafka 组件的脚本使用这些属性。

流程

  1. 使用 JMX 属性设置 KAFKA_JMX_OPTS 环境变量以启用 JMX 监控。

    export KAFKA_JMX_OPTS=-Dcom.sun.management.jmxremote=true
      -Dcom.sun.management.jmxremote.port=<port>
      -Dcom.sun.management.jmxremote.authenticate=false
      -Dcom.sun.management.jmxremote.ssl=false

    将 <port> 替换为您要 Kafka 组件侦听 JMX 连接的端口名称。

  2. org.apache.kafka.common.metrics.JmxReporter 添加到 server.properties 文件中的 metric.reporters

    metric.reporters=org.apache.kafka.common.metrics.JmxReporter
  3. 使用适当的脚本启动 Kafka 组件,如 bin/kafka-server-start.sh 用于代理,或 bin/connect-distributed.sh 用于 Kafka Connect。
重要

建议您配置身份验证和 SSL 来保护远程 JMX 连接。有关执行此操作所需的系统属性的更多信息,请参阅 Oracle 文档

20.2. 禁用 JMX 代理

通过更新 KAFKA_JMX_OPTS 环境变量来禁用 Kafka 组件的 JMX 监控。

流程

  1. 设置 KAFKA_JMX_OPTS 环境变量以禁用 JMX 监控。

    export KAFKA_JMX_OPTS=-Dcom.sun.management.jmxremote=false
    注意

    禁用 JMX 监控时不需要指定其他 JMX 属性,如端口、身份验证和 SSL 属性。

  2. 在 Kafka server.properties 文件中,将 auto.include.jmx.reporter 设置为 false

    auto.include.jmx.reporter=false
    注意

    auto.include.jmx.reporter 属性已弃用。从 Kafka 4 中,只有 org.apache.kafka.common.metrics.JmxReporter 添加到属性文件中的 metric.reporters 配置中时,才会启用 JMXReporter。

  3. 使用适当的脚本启动 Kafka 组件,如 bin/kafka-server-start.sh 用于代理,或 bin/connect-distributed.sh 用于 Kafka Connect。

20.3. 指标命名约定

在使用 Kafka JMX 指标时,务必要理解用于识别和检索特定指标的命名约定。Kafka JMX 指标使用以下格式:

指标格式

<metric_group>:type=<type_name>,name=<metric_name><other_attribute>=<value>

  • <metric_group> 是指标组的名称
  • <type_name> 是指标类型的名称
  • <metric_name> 是特定指标的名称
  • <other_attribute> 代表零个或多个附加属性

例如,BytesInPerSec 指标是 kafka.server 组中的 BrokerTopicMetrics 类型:

kafka.server:type=BrokerTopicMetrics,name=BytesInPerSec

在某些情况下,指标可能包含实体的 ID。例如,在监控特定客户端时,指标格式包括客户端 ID:

特定客户端的指标

kafka.consumer:type=consumer-fetch-manager-metrics,client-id=<client_id>

同样,指标可以进一步缩小到特定的客户端和主题:

特定客户端和主题的指标

kafka.consumer:type=consumer-fetch-manager-metrics,client-id=<client_id>,topic=<topic_id>

了解这些命名约定将允许您准确指定要监控的指标。

注意

要查看 Strimzi 安装的可用 JMX 指标的完整列表,您可以使用 JConsole 等图形化工具。JConsole 是一个 Java 监控和管理控制台,允许您监控和管理 Java 应用程序,包括 Kafka。通过使用其进程 ID 连接到运行 Kafka 组件的 JVM,工具的用户界面允许您查看指标列表。

20.4. 分析 Kafka JMX 指标以进行故障排除

JMX 提供了收集有关 Kafka 代理的指标来监控和管理其性能和资源使用情况的方法。通过分析这些指标,可以诊断和解决常见的代理问题,如高 CPU 使用量、内存泄漏、线程争用和慢响应时间。某些指标可能会识别这些问题的根本原因。

JMX 指标还深入了解 Kafka 集群的整体健康状况和性能。它们有助于监控系统的吞吐量、延迟和可用性、诊断问题并优化性能。本节探索使用 JMX 指标来帮助识别常见问题,并深入了解 Kafka 集群的性能。

使用 Prometheus 和 Grafana 等工具收集和绘制这些指标,您可以视觉化返回的信息。这在检测问题或优化性能方面特别有用。随着时间的推移图表指标还可帮助识别趋势和预测资源消耗。

20.4.1. 检查不复制的分区

对于最佳性能,平衡 Kafka 集群非常重要。在均衡集群中,分区和领导在所有代理中平均分布,I/O 指标反映了这一点。除了使用指标外,您可以使用 kafka-topics.sh 工具获取没有复制的分区列表,并确定有问题的代理。如果不复制的分区数量发生变化,或者许多代理显示高请求延迟,这通常表示集群中需要调查的集群中的性能问题。另一方面,集群中许多代理报告的大量未复制分区数量通常表示集群中的其中一个代理离线。

使用 kafka-topics.sh 工具中的 describe --under-replicated-partitions 选项来显示集群中当前复制的分区的信息。这些分区的副本少于配置的复制因素。

如果输出为空,则 Kafka 集群没有复制分区。否则,输出显示没有同步或可用的副本。

在以下示例中,每个分区只有 3 个中的 2 个副本同步,ISR (同步副本)中缺少一个副本。

从命令行返回有关复制分区的信息

bin/kafka-topics.sh --bootstrap-server :9092 --describe --under-replicated-partitions

Topic: topic-1 Partition: 0 Leader: 4 Replicas: 4,2,3 Isr: 4,3
Topic: topic-1 Partition: 1 Leader: 3 Replicas: 2,3,4 Isr: 3,4
Topic: topic-1 Partition: 2 Leader: 3 Replicas: 3,4,2 Isr: 3,4

以下是检查 I/O 和复制分区的一些指标:

检查复制分区的指标

kafka.server:type=ReplicaManager,name=PartitionCount 1
kafka.server:type=ReplicaManager,name=LeaderCount 2
kafka.server:type=BrokerTopicMetrics,name=BytesInPerSec 3
kafka.server:type=BrokerTopicMetrics,name=BytesOutPerSec 4
kafka.server:type=ReplicaManager,name=UnderReplicatedPartitions 5
kafka.server:type=ReplicaManager,name=UnderMinIsrPartitionCount 6

1
集群中所有主题的分区总数。
2
集群中所有主题的领导总数。
3
每个代理的传入字节数。
4
每个代理的传出字节数。
5
在集群中的所有主题间复制分区的数量。
6
最小 ISR 下的分区数量。

如果为高可用性设置了主题配置,则主题至少为 3 的复制因素,最小同步副本的数量小于复制因素 1 个,没有复制的分区仍然可以使用。相反,低于最低 ISR 的分区会减少可用性。您可以使用 kafka-topics.sh 工具中的 kafka.server:type=ReplicaManager,name=UnderMinIsrPartitionCount 指标和 under-min-isr-partitions 选项来监控它们。

提示

使用 Cruise Control 自动监控和重新平衡 Kafka 集群的任务,以确保平均分配分区负载。如需更多信息,请参阅 第 14 章 使用 Cruise Control 进行集群重新平衡

20.4.2. 识别 Kafka 集群中的性能问题

集群指标中的激增可能会表示代理问题,与其他进程的速度或出现故障的存储设备或计算其他进程的影响通常相关。如果在操作系统或硬件级别出现问题,则 Kafka 集群的负载可能会有不平衡,一些分区可能会收到与同一 Kafka 主题中的其他流量相关的分散流量。

要预期 Kafka 集群中的性能问题,监控 RequestHandlerAvgIdlePercent 指标会很有用。RequestHandlerAvgIdlePercent 提供有关集群的行为方式的良好总体指示。此指标的值介于 0 到 1 之间。下面的值 0.7 表示线程在时间忙碌的 30%,性能开始降级。如果值低于 50%,则可能会出现问题,特别是当集群需要扩展或重新平衡时。在 30% 时,集群裸机可用。

另一个有用的指标是 kafka.network:type=Processor,name=IdlePercent,您可以使用它来监控 Kafka 集群中网络处理器闲置的扩展(作为百分比)。指标有助于识别处理器是否已超过或未被充分利用。

为确保最佳性能,请设置与系统中处理器数量相等的 num.io.threads 属性,包括超线程处理器。如果集群是均衡的,但单个客户端更改了其请求模式,并导致问题,减少集群的负载或增加代理数量。

请注意,在单个代理中单个磁盘失败可能会严重影响整个集群的性能。由于生成者客户端连接到导致主题分区的所有代理,且这些分区会均匀地分散到整个集群上,因此执行失败的代理会减慢生成请求并导致生成者中的后端压力,并减慢所有代理的请求速度。将多个物理磁盘驱动器组合成一个逻辑单元的 RAID (冗余磁盘阵列)存储配置可帮助防止这个问题。

以下是检查 Kafka 集群性能的一些指标:

检查 Kafka 集群性能的指标

kafka.server:type=KafkaRequestHandlerPool,name=RequestHandlerAvgIdlePercent 1
# attributes: OneMinuteRate, FifteenMinuteRate
kafka.server:type=socket-server-metrics,listener=([-.\w]+),networkProcessor=([\d]+) 2
# attributes: connection-creation-rate
kafka.network:type=RequestChannel,name=RequestQueueSize 3
kafka.network:type=RequestChannel,name=ResponseQueueSize 4
kafka.network:type=Processor,name=IdlePercent,networkProcessor=([-.\w]+) 5
kafka.server:type=KafkaServer,name=TotalDiskReadBytes 6
kafka.server:type=KafkaServer,name=TotalDiskWriteBytes 7

1
Kafka 代理线程池中请求处理器线程的平均空闲百分比。OneMinuteRateFifteenMinuteRate 属性分别显示最后一分钟和十五分钟的请求率。
2
在 Kafka 代理中特定监听程序的特定网络处理器上创建新连接的速度。listener 属性引用监听器的名称,networkProcessor 属性指的是网络处理器的 ID。connection-creation-rate 属性显示每秒连接创建率。
3
请求队列的当前大小。
4
响应队列的当前大小。
5
指定网络处理器闲置的时间百分比。networkProcessor 指定要监控的网络处理器的 ID。
6
Kafka 服务器从磁盘读取的字节数。
7
Kafka 服务器写入磁盘的字节数。

20.4.3. 识别 Kafka 控制器的性能问题

Kafka 控制器负责管理集群的整体状态,如代理注册、分区重新分配和主题管理。Kafka 集群中控制器的问题难以诊断,通常属于 Kafka 本身中的错误类别。控制器问题可能会清单为代理元数据不同步,当代理看起来正常时,或者对主题创建等主题的操作没有正确发生时离线副本。

很多监控控制器的方法,但您可以监控活跃控制器计数和控制器队列大小。如果出现问题,监控这些指标会给出高级别指示符。虽然队列大小中的激增是正常的,但如果这个值持续增加,或者保持高值,也不会丢弃,这表示控制器可能会卡住。如果您遇到这个问题,您可以将控制器移到不同的代理中,这需要关闭当前控制器的代理。

以下是检查 Kafka 控制器性能的一些指标:

检查 Kafka 控制器性能的指标

kafka.controller:type=KafkaController,name=ActiveControllerCount 1
kafka.controller:type=KafkaController,name=OfflinePartitionsCount 2
kafka.controller:type=ControllerEventManager,name=EventQueueSize 3

1
Kafka 集群中的活跃控制器数量。值 1 表示只有一个活跃的控制器,它是所需的状态。
2
当前离线的分区数。如果这个值持续增长或保持高值,则控制器可能会出现问题。
3
控制器中的事件队列的大小。事件是必须由控制器执行的操作,如创建新主题或将分区移到新代理。如果值持续增加或保持高值,控制器可能会卡住且无法执行所需操作。

20.4.4. 识别请求的问题

您可以使用 RequestHandlerAvgIdlePercent 指标来确定请求是否慢。另外,请求指标可以识别哪些特定请求遇到延迟和其他问题。

要有效地监控 Kafka 请求,收集两个关键指标至关重要: count 和 99th percentile 延迟(也称为 tail 延迟)。

count 指标表示在特定时间间隔内处理的请求数。它可让您了解 Kafka 集群处理的请求卷,并帮助识别流量中的 spikes 或丢弃。

99th percentile 延迟测量请求延迟,这是处理请求的时间。它代表了处理 99% 请求的持续时间。但是,它不会提供有关剩余 1% 请求的确切持续时间的信息。换句话说,99th percentile 的延迟指标告知您在一定时间内处理 99% 的请求,剩余的 1% 可能需要更长时间,但这种剩余 1% 的精确持续时间未知。99%ile 的选择主要侧重于大多数请求,并排除可以偏移结果的排除者。

此指标在识别与大多数请求相关的性能问题和瓶颈时特别有用,但不给出少量请求所遇到的最大延迟的完整列表。

通过收集和分析 count 和 99th percentile 延迟指标,您可以了解 Kafka 集群的整体性能和健康状况,以及正在处理请求的延迟。

以下是检查 Kafka 请求性能的一些指标:

检查请求性能的指标

# requests: EndTxn, Fetch, FetchConsumer, FetchFollower, FindCoordinator, Heartbeat, InitProducerId,
# JoinGroup, LeaderAndIsr, LeaveGroup, Metadata, Produce, SyncGroup, UpdateMetadata 1
kafka.network:type=RequestMetrics,name=RequestsPerSec,request=([\w]+) 2
kafka.network:type=RequestMetrics,name=RequestQueueTimeMs,request=([\w]+) 3
kafka.network:type=RequestMetrics,name=TotalTimeMs,request=([\w]+) 4
kafka.network:type=RequestMetrics,name=LocalTimeMs,request=([\w]+) 5
kafka.network:type=RequestMetrics,name=RemoteTimeMs,request=([\w]+) 6
kafka.network:type=RequestMetrics,name=ThrottleTimeMs,request=([\w]+) 7
kafka.network:type=RequestMetrics,name=ResponseQueueTimeMs,request=([\w]+) 8
kafka.network:type=RequestMetrics,name=ResponseSendTimeMs,request=([\w]+) 9
# attributes: Count, 99thPercentile 10

1
请求类型以中断请求指标。
2
Kafka 代理每秒处理请求的速率。
3
请求在处理前等待代理请求队列的时间(以毫秒为单位)。
4
请求完成所需的时间(以毫秒为单位),从代理收到的时间到响应返回客户端的时间。
5
请求由本地计算机上的代理处理的时间(以毫秒为单位)。
6
请求由集群中的其他代理处理的时间(以毫秒为单位)。
7
代理节流的请求花费的时间(以毫秒为单位)。当代理决定客户端发送太多的请求速度过慢且需要减慢时,会发生节流。
8
在返回到客户端前,响应在代理响应队列中等待的时间(以毫秒为单位)。
9
代理生成后响应要发送到客户端的时间(以毫秒为单位)。
10
对于所有请求指标,Count99thPercentile 属性显示已处理的请求总数,以及分别完成最多 1% 的请求所需的时间。

20.4.5. 使用指标检查客户端的性能

通过分析客户端指标,您可以监控连接到代理的 Kafka 客户端(producers 和 consumers)的性能。这有助于识别代理日志中突出显示的问题,如消费者经常关闭其消费者组、高请求故障率或频繁断开连接。

以下是检查 Kafka 客户端性能的一些指标:

检查客户端请求性能的指标

kafka.consumer:type=consumer-metrics,client-id=([-.\w]+) 1
# attributes: time-between-poll-avg, time-between-poll-max
kafka.consumer:type=consumer-coordinator-metrics,client-id=([-.\w]+) 2
# attributes: heartbeat-response-time-max, heartbeat-rate, join-time-max, join-rate, rebalance-rate-per-hour
kafka.producer:type=producer-metrics,client-id=([-.\w]+) 3
# attributes: buffer-available-bytes, bufferpool-wait-time, request-latency-max, requests-in-flight
# attributes: txn-init-time-ns-total, txn-begin-time-ns-total, txn-send-offsets-time-ns-total, txn-commit-time-ns-total, txn-abort-time-ns-total
# attributes: record-error-total, record-queue-time-avg, record-queue-time-max, record-retry-rate, record-retry-total, record-send-rate, record-send-total

1
(消费者)轮询请求之间平均和最长时间,这有助于确定消费者是否频繁轮询消息以保持消息流。time-between-poll-avgtime-between-poll-max 属性分别显示消费者连续轮询之间的平均和最长时间(毫秒)。
2
(consumer)监控 Kafka 用户和代理协调器之间的协调过程的指标。属性与心跳、加入和重新平衡过程相关。
3
(producer)监控 Kafka producer 的性能的指标。属性与缓冲区使用量、请求延迟、动态请求、事务处理和记录处理相关。

20.4.6. 使用指标检查主题和分区的性能

主题和分区的指标还有助于诊断 Kafka 集群中的问题。当无法收集客户端指标时,您还可以使用它们调试特定客户端的问题。

以下是检查特定主题和分区性能的一些指标:

检查主题和分区性能的指标

#Topic metrics
kafka.server:type=BrokerTopicMetrics,name=BytesInPerSec,topic=([-.\w]+) 1
kafka.server:type=BrokerTopicMetrics,name=BytesOutPerSec,topic=([-.\w]+) 2
kafka.server:type=BrokerTopicMetrics,name=FailedFetchRequestsPerSec,topic=([-.\w]+) 3
kafka.server:type=BrokerTopicMetrics,name=FailedProduceRequestsPerSec,topic=([-.\w]+) 4
kafka.server:type=BrokerTopicMetrics,name=MessagesInPerSec,topic=([-.\w]+) 5
kafka.server:type=BrokerTopicMetrics,name=TotalFetchRequestsPerSec,topic=([-.\w]+) 6
kafka.server:type=BrokerTopicMetrics,name=TotalProduceRequestsPerSec,topic=([-.\w]+) 7
#Partition metrics
kafka.log:type=Log,name=Size,topic=([-.\w]+),partition=([\d]+)) 8
kafka.log:type=Log,name=NumLogSegments,topic=([-.\w]+),partition=([\d]+)) 9
kafka.log:type=Log,name=LogEndOffset,topic=([-.\w]+),partition=([\d]+)) 10
kafka.log:type=Log,name=LogStartOffset,topic=([-.\w]+),partition=([\d]+)) 11

1
特定主题每秒的传入字节数。
2
特定主题每秒传出字节数。
3
特定主题每秒失败的请求率。
4
生成特定主题每秒失败的请求数。
5
特定主题每秒的传入消息率。
6
特定主题每秒获取请求的总数(成功和失败)。
7
特定主题每秒获取请求的总数(成功和失败)。
8
特定分区日志的大小(以字节为单位)。
9
特定分区中的日志片段数。
10
特定分区日志中最后一个消息的偏移量。
11
特定分区日志中第一个消息的偏移

其他资源

附录 A. 使用您的订阅

AMQ Streams 通过软件订阅提供。要管理您的订阅,请访问红帽客户门户中的帐户。

访问您的帐户

  1. 转至 access.redhat.com
  2. 如果您还没有帐户,请创建一个帐户。
  3. 登录到您的帐户。

激活订阅

  1. 转至 access.redhat.com
  2. 导航到 My Subscriptions
  3. 导航到 激活订阅 并输入您的 16 位激活号。

下载 Zip 和 Tar 文件

要访问 zip 或 tar 文件,请使用客户门户网站查找下载的相关文件。如果您使用 RPM 软件包,则不需要这一步。

  1. 打开浏览器并登录红帽客户门户网站 产品下载页面,网址为 access.redhat.com/downloads
  2. INTEGRATION AND AUTOMATION 目录中找到 AMQ Streams for Apache Kafka 项。
  3. 选择所需的 AMQ Streams 产品。此时会打开 Software Downloads 页面。
  4. 单击组件的 Download 链接。

使用 DNF 安装软件包

要安装软件包以及所有软件包的依赖软件包,请使用:

dnf install <package_name>

要从本地目录中安装之前下载的软件包,请使用:

dnf install <path_to_download_package>

更新于 2024-03-21

法律通告

Copyright © 2024 Red Hat, Inc.
The text of and illustrations in this document are licensed by Red Hat under a Creative Commons Attribution–Share Alike 3.0 Unported license ("CC-BY-SA"). An explanation of CC-BY-SA is available at http://creativecommons.org/licenses/by-sa/3.0/. In accordance with CC-BY-SA, if you distribute this document or an adaptation of it, you must provide the URL for the original version.
Red Hat, as the licensor of this document, waives the right to enforce, and agrees not to assert, Section 4d of CC-BY-SA to the fullest extent permitted by applicable law.
Red Hat, Red Hat Enterprise Linux, the Shadowman logo, the Red Hat logo, JBoss, OpenShift, Fedora, the Infinity logo, and RHCE are trademarks of Red Hat, Inc., registered in the United States and other countries.
Linux® is the registered trademark of Linus Torvalds in the United States and other countries.
Java® is a registered trademark of Oracle and/or its affiliates.
XFS® is a trademark of Silicon Graphics International Corp. or its subsidiaries in the United States and/or other countries.
MySQL® is a registered trademark of MySQL AB in the United States, the European Union and other countries.
Node.js® is an official trademark of Joyent. Red Hat is not formally related to or endorsed by the official Joyent Node.js open source or commercial project.
The OpenStack® Word Mark and OpenStack logo are either registered trademarks/service marks or trademarks/service marks of the OpenStack Foundation, in the United States and other countries and are used with the OpenStack Foundation's permission. We are not affiliated with, endorsed or sponsored by the OpenStack Foundation, or the OpenStack community.
All other trademarks are the property of their respective owners.