9.12. 配置 Kafka 和 ZooKeeper 存储


Apache Kafka 的流提供了配置 Kafka 和 ZooKeeper 数据存储选项的灵活性。

支持的存储类型有:

  • Ephemeral (推荐只在开发时使用)
  • 持久性
  • JBOD (只限 Kafka;对于 ZooKeeper 不可用)
  • 分层存储(Early access)

要配置存储,您可以在组件的自定义资源中指定 storage 属性。存储类型使用 storage.type 属性设置。使用节点池时,您可以指定 Kafka 集群中使用的每个节点池的唯一存储配置。Kafka 资源可用的相同存储属性也可用于 KafkaNodePool 池资源。

分层存储通过利用具有不同特征的并行使用存储类型,为数据管理提供了更大的灵活性。例如,分层存储可能包括:

  • 更高的性能和更高的成本块存储
  • 降低性能并降低成本对象存储

分层存储是 Kafka 中的早期访问功能。要配置分层存储,您可以指定 分层存储 属性。分层存储仅在使用 Kafka 自定义资源的集群级别进行配置。

与存储相关的模式引用提供有关存储配置属性的更多信息:

警告

部署 Kafka 集群后无法更改存储类型。

9.12.1. 数据存储注意事项

要使 Apache Kafka 正常工作的流,高效的数据存储基础架构非常重要。我们强烈建议您使用块存储。Apache Kafka 的流只测试用于块存储。文件存储(如 NFS)没有被测试,无法保证它可以正常工作。

为您的块存储选择以下选项之一:

注意

Apache Kafka 的流不需要 OpenShift 原始块卷。

9.12.1.1. 文件系统

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

如需更多信息,请参阅 Kafka 文档中的 Filesystem Selection

9.12.1.2. 磁盘用量

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

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

注意

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

9.12.2. 临时存储

临时数据存储是临时的。节点上的所有 pod 共享本地临时存储空间。只要使用它的 pod 正在运行,数据就会保留。当 pod 被删除时,数据会丢失。虽然 pod 可以在高可用性环境中恢复数据。

由于其临时性质,仅推荐使用临时存储进行开发和测试。

临时存储使用 emptyDir 卷来存储数据。当 pod 分配给节点时,会创建一个 emptyDir 卷。您可以使用 sizeLimit 属性为 emptyDir 设置存储总量。

重要

临时存储不适用于单节点 ZooKeeper 集群或 Kafka 主题,复制因子为 1。

要使用临时存储,您可以将 KafkaZooKeeper 资源中的存储类型配置设置为 临时。如果使用节点池,也可以在单个节点池的存储配置中指定 ephemeral

临时存储配置示例

apiVersion: kafka.strimzi.io/v1beta2
kind: Kafka
metadata:
  name: my-cluster
spec:
  kafka:
    storage:
      type: ephemeral
    # ...
  zookeeper:
    storage:
      type: ephemeral
    # ...
Copy to Clipboard Toggle word wrap

9.12.2.1. Kafka 日志目录的挂载路径

Kafka 代理使用临时卷来作为挂载到以下路径的日志目录:

/var/lib/kafka/data/kafka-logIDX
Copy to Clipboard Toggle word wrap

其中 IDX 是 Kafka 代理 pod 索引。例如 /var/lib/kafka/data/kafka-log0

9.12.3. 持久性存储

持久数据存储在系统中断时保留数据。对于使用持久数据存储的 pod,数据会在 pod 失败后保留,并重启。由于其永久性质,建议在生产环境中使用持久性存储。

以下示例显示了 OpenShift 支持的通用持久性卷类型:

  • 如果您的 OpenShift 集群在 Amazon AWS 上运行,OpenShift 可以置备 Amazon EBS 卷
  • 如果您的 OpenShift 集群在 Microsoft Azure 上运行,OpenShift 可以置备 Azure Disk Storage 卷
  • 如果您的 OpenShift 集群在 Google Cloud 上运行,OpenShift 可以置备 Persistent Disk 卷
  • 如果您的 OpenShift 集群在裸机上运行,OpenShift 可以置备本地持久性卷

要使用 Apache Kafka 的 Streams 中的持久性存储,您可以在 KafkaZooKeeper 资源的存储配置中指定 persistent-claim。如果使用节点池,也可以在单个节点池的存储配置中指定 persistent-claim

您可以配置资源,以便 pod 使用 持久性卷声明 (PVC) 在持久性卷 (PV) 上发出存储请求。PV 代表按需创建的存储卷,并独立于使用它们的 pod。PVC 请求创建 pod 时所需的存储量。PV 的底层存储基础架构不需要理解。如果 PV 与存储条件匹配,PVC 会绑定到 PV。

您有两个选项来指定存储类型:

storage.type: persistent-claim
如果您选择 persistent-claim 作为存储类型,则会定义一个持久性存储卷。
storage.type: jbod
当您选择 jbod 作为存储类型时,您可以灵活地使用唯一 ID 定义一组持久性存储卷。

在生产环境中,建议配置以下内容:

  • 对于 Kafka 或节点池,使用一个或多个持久性卷将 storage.type 设置为 jbod
  • 对于 ZooKeeper,将 storage.type 设置为单个持久性卷的 persistent-claim

持久性存储还具有以下配置选项:

id (可选)
存储标识号。对于 JBOD 存储声明中定义的存储卷,这个选项是必须的。默认值为 0。
Size (必需)
持久性卷声明的大小,如 "1000Gi"。
(可选)
PVC 可以通过指定 StorageClass 来请求不同类型的持久性存储。存储类定义存储配置集,并根据该配置集动态置备 PV。如果没有指定存储类,则使用 OpenShift 集群中标记为 default 的存储类。持久性存储选项可能包括 SAN 存储类型或本地持久性卷
selector (可选)
配置以指定特定 PV。提供 key:value 对,代表所选卷的标签。
deleteClaim (optional)
布尔值,用于指定在卸载集群时是否删除 PVC。默认为 false
警告

只有在支持持久性卷大小的 OpenShift 版本中,才支持增大 Apache Kafka 集群现有流中的持久性卷大小。要重新定义大小的持久性卷必须使用支持卷扩展的存储类。对于不支持卷扩展的 OpenShift 和存储类的其他版本,您必须在部署集群前决定必要的存储大小。无法减少现有持久性卷的大小。

Kafka 和 ZooKeeper 持久性存储配置示例

apiVersion: kafka.strimzi.io/v1beta2
kind: Kafka
metadata:
  name: my-cluster
spec:
  kafka:
    storage:
      type: jbod
      volumes:
      - id: 0
        type: persistent-claim
        size: 100Gi
        deleteClaim: false
      - id: 1
        type: persistent-claim
        size: 100Gi
        deleteClaim: false
      - id: 2
        type: persistent-claim
        size: 100Gi
        deleteClaim: false
    # ...
  zookeeper:
    storage:
      type: persistent-claim
      size: 1000Gi
    # ...
Copy to Clipboard Toggle word wrap

使用特定存储类的持久性存储配置示例

# ...
storage:
  type: persistent-claim
  size: 500Gi
  class: my-storage-class
# ...
Copy to Clipboard Toggle word wrap

使用选择器 (selector)来指定提供某些功能的标记的持久性卷,如 SSD。

使用选择器的持久性存储配置示例

# ...
storage:
  type: persistent-claim
  size: 1Gi
  selector:
    hdd-type: ssd
  deleteClaim: true
# ...
Copy to Clipboard Toggle word wrap

9.12.3.1. 存储类覆盖

警告

存储类覆盖已弃用,并将在以后的发行版本中删除。作为替换,使用 KafkaNodePool 资源替代。

您可以为一个或多个 Kafka 或 ZooKeeper 节点指定不同的存储类,而不是使用默认存储类。例如,当存储类仅限于不同的可用区或数据中心时,这非常有用。您可以使用 overrides 字段来实现这一目的。

在本例中,默认存储类名为 my-storage-class

带有类覆盖的存储配置示例

apiVersion: kafka.strimzi.io/v1beta2
kind: Kafka
metadata:
  labels:
    app: my-cluster
  name: my-cluster
  namespace: myproject
spec:
  # ...
  kafka:
    replicas: 3
    storage:
      type: jbod
      volumes:
      - id: 0
        type: persistent-claim
        size: 100Gi
        deleteClaim: false
        class: my-storage-class
        overrides:
        - broker: 0
          class: my-storage-class-zone-1a
        - broker: 1
          class: my-storage-class-zone-1b
        - broker: 2
          class: my-storage-class-zone-1c
      # ...
  # ...
  zookeeper:
    replicas: 3
    storage:
      deleteClaim: true
      size: 100Gi
      type: persistent-claim
      class: my-storage-class
      overrides:
        - broker: 0
          class: my-storage-class-zone-1a
        - broker: 1
          class: my-storage-class-zone-1b
        - broker: 2
          class: my-storage-class-zone-1c
  # ...
Copy to Clipboard Toggle word wrap

由于配置的 overrides 属性,卷使用以下存储类:

  • ZooKeeper 节点 0 的持久性卷使用 my-storage-class-zone-1a
  • ZooKeeper 节点 1 的持久性卷使用 my-storage-class-zone-1b
  • ZooKeeper 节点 2 的持久性卷使用 my-storage-class-zone-1c
  • Kafka 代理 0 的持久性卷使用 my-storage-class-zone-1a
  • Kafka 代理 1 的持久性卷使用 my-storage-class-zone-1b
  • Kafka 代理 2 的持久性卷使用 my-storage-class-zone-1c

overrides 属性目前仅用于覆盖存储。目前不支持对其他存储配置属性覆盖。

9.12.3.1.1. 从存储类覆盖迁移到节点池

存储类覆盖已弃用,并将在以后的发行版本中删除。如果您使用存储类覆盖,我们建议您使用节点池。要迁移现有配置,请按照以下步骤执行:

  1. 确保您已使用节点池资源。如果没有,您应该先 迁移集群以使用节点池
  2. 使用所需的存储类创建带有存储配置 的新节点池,而无需使用覆盖。
  3. 使用存储类覆盖的旧代理中移动所有分区副本。您可以使用 Cruise Control 或使用分区重新分配工具 完成此操作。
  4. 使用存储类覆盖的旧代理删除旧节点池。

9.12.3.2. 持久性存储的 PVC 资源

使用持久性存储时,它会使用以下名称创建 PVC:

data-cluster-name-kafka-idx
用于存储 Kafka 代理 pod idx 数据的卷的 PVC。
data-cluster-name-zookeeper-idx
用于为 ZooKeeper 节点 pod idx 存储数据的卷的 PVC。

9.12.3.3. Kafka 日志目录的挂载路径

Kafka 代理使用持久性卷作为挂载到以下路径的日志目录:

/var/lib/kafka/data/kafka-logIDX
Copy to Clipboard Toggle word wrap

其中 IDX 是 Kafka 代理 pod 索引。例如 /var/lib/kafka/data/kafka-log0

9.12.4. 重新调整持久性卷大小

只要存储基础架构支持,就可以调整集群使用的持久性卷而不造成数据丢失的风险。在进行了配置更新以更改存储的大小后,Apache Kafka 的 Streams 指示存储基础架构进行更改。使用 persistent-claim 卷的 Apache Kafka 集群支持存储扩展。

只有在每个代理使用多个磁盘时,才能减少存储。在将磁盘中的所有分区移动到同一代理(intra-broker)或同一集群(集群内)中的其他代理后,您可以删除磁盘。

重要

您无法缩小持久性卷的大小,因为它目前在 OpenShift 中不被支持。

先决条件

  • 支持调整大小的 OpenShift 集群。
  • Cluster Operator 正在运行。
  • 使用支持卷扩展的存储类创建的持久性卷的 Kafka 集群。

流程

  1. 编辑集群的 Kafka 资源。

    更改 size 属性,以增加分配给 Kafka 集群、ZooKeeper 集群或两者的持久性卷大小。

    • 对于 Kafka 集群,更新 spec.kafka.storage 下的 size 属性。
    • 对于 ZooKeeper 集群,更新 spec.zookeeper.storage 下的 size 属性。

    将卷大小增加到 2000Gi的 Kafka 配置

    apiVersion: kafka.strimzi.io/v1beta2
    kind: Kafka
    metadata:
      name: my-cluster
    spec:
      kafka:
        # ...
        storage:
          type: persistent-claim
          size: 2000Gi
          class: my-storage-class
        # ...
      zookeeper:
        # ...
    Copy to Clipboard Toggle word wrap

  2. 创建或更新资源:

    oc apply -f <kafka_configuration_file>
    Copy to Clipboard Toggle word wrap

    OpenShift 增加所选持久性卷的容量,以响应 Cluster Operator 的请求。完成调整大小后,Cluster Operator 会重启所有使用调整大小的持久性卷的 pod。这会自动发生。

  3. 验证集群中相关 pod 的存储容量是否已增加:

    oc get pv
    Copy to Clipboard Toggle word wrap

    带有增加存储的 Kafka 代理 pod

    NAME               CAPACITY   CLAIM
    pvc-0ca459ce-...   2000Gi     my-project/data-my-cluster-kafka-2
    pvc-6e1810be-...   2000Gi     my-project/data-my-cluster-kafka-0
    pvc-82dc78c9-...   2000Gi     my-project/data-my-cluster-kafka-1
    Copy to Clipboard Toggle word wrap

    输出显示了与代理 pod 关联的每个 PVC 的名称。

9.12.5. JBOD 存储

JBOD 存储允许您将 Kafka 集群配置为使用多个磁盘或卷。此方法为 Kafka 节点提供数据存储容量,并可能导致性能改进。JBOD 配置由一个或多个卷定义,每个卷可以是 临时持久。JBOD 卷声明的规则和约束与临时存储和持久性存储的规则和约束相同。例如,在置备后,您无法缩小持久性存储卷的大小,当类型为 临时 时,您无法更改 sizeLimit 的值。

注意

对 JBOD 存储的支持仅限 Kafka,不支持 ZooKeeper。

要使用 JBOD 存储,您可以将 Kafka 资源中的存储类型配置设置为 jbod。如果使用节点池,也可以在存储配置中指定属于特定节点池的节点的 jbod

volumes 属性允许您描述组成 JBOD 存储阵列或配置的磁盘。

JBOD 存储配置示例

apiVersion: kafka.strimzi.io/v1beta2
kind: Kafka
metadata:
  name: my-cluster
spec:
  kafka:
    storage:
      type: jbod
      volumes:
      - id: 0
        type: persistent-claim
        size: 100Gi
        deleteClaim: false
      - id: 1
        type: persistent-claim
        size: 100Gi
        deleteClaim: false
  # ...
Copy to Clipboard Toggle word wrap

创建 JBOD 卷后无法更改 ID。您可以从 JBOD 配置中添加或删除卷。

9.12.5.1. JBOD 存储的 PVC 资源

当持久性存储用于声明 JBOD 卷时,它会创建一个具有以下名称的 PVC:

data-id-cluster-name-kafka-idx
用于存储 Kafka 代理 pod idx 数据的卷的 PVC。id 是用于存储 Kafka 代理 pod 数据的卷的 ID。

9.12.5.2. Kafka 日志目录的挂载路径

Kafka 代理使用 JBOD 卷作为挂载到以下路径的日志目录:

/var/lib/kafka/data-id/kafka-logidx
Copy to Clipboard Toggle word wrap

其中 id 是用于存储 Kafka 代理 pod idx 数据的卷的 ID。例如 /var/lib/kafka/data-0/kafka-log0

在 KRaft 模式中,Kafka 集群元数据日志的副本会在每个节点上存储,包括代理和控制器。每个节点都使用其数据卷之一进行 KRaft 元数据日志。默认情况下,日志存储在 ID 最低的卷中。但是,您可以使用 kraftMetadata 属性指定另一个卷。

对于没有处理数据的仅控制器节点,存储仅用于元数据日志。元数据日志始终仅存储在一个卷中,因此使用带有多个卷的 JBOD 存储无法提高性能或提高可用磁盘空间。

同时,代理节点或节点组合代理和控制器角色共享相同的卷来存储元数据日志和分区副本数据。这种共享可优化磁盘利用率。它们还可以使用多个卷来使用 JBOD 存储,以便其中一个卷由元数据日志和分区副本数据共享,而任何其他卷则仅用于分区副本数据。

更改存储元数据日志的卷会触发集群中节点的滚动更新。这个过程涉及删除旧元数据日志并在新位置创建新元数据。如果没有在任何卷上指定 kraftMetadata,添加具有较低 ID 的新卷也会触发元数据日志的更新和重定位。

注意

KRaft 模式中的 JBOD 存储被视为 Apache Kafka 3.7.x 中的 early-access。

使用 ID 为 1 的卷的 JBOD 存储配置示例来存储 KRaft 元数据

apiVersion: kafka.strimzi.io/v1beta2
kind: KafkaNodePool
metadata:
  name: pool-a
  # ...
spec:
  storage:
    type: jbod
    volumes:
    - id: 0
      type: persistent-claim
      size: 100Gi
      deleteClaim: false
    - id: 1
      type: persistent-claim
      size: 100Gi
      kraftMetadata: shared
      deleteClaim: false
  # ...
Copy to Clipboard Toggle word wrap

9.12.6. 将卷添加到 JBOD 存储

此流程描述了如何将卷添加到配置为使用 JBOD 存储的 Kafka 集群中。它不能应用到配置为使用任何其他存储类型的 Kafka 集群。

注意

当在过去和删除的 id 下添加新卷时,您必须确保之前使用的 PersistentVolumeClaims 已被删除。

先决条件

  • 一个 OpenShift 集群
  • 正在运行的 Cluster Operator
  • 具有 JBOD 存储的 Kafka 集群

流程

  1. 编辑 Kafka 资源中的 spec.kafka.storage.volumes 属性。将新卷添加到 volumes 数组中。例如,使用 id 2 添加新卷:

    apiVersion: kafka.strimzi.io/v1beta2
    kind: Kafka
    metadata:
      name: my-cluster
    spec:
      kafka:
        # ...
        storage:
          type: jbod
          volumes:
          - id: 0
            type: persistent-claim
            size: 100Gi
            deleteClaim: false
          - id: 1
            type: persistent-claim
            size: 100Gi
            deleteClaim: false
          - id: 2
            type: persistent-claim
            size: 100Gi
            deleteClaim: false
        # ...
      zookeeper:
        # ...
    Copy to Clipboard Toggle word wrap
  2. 创建或更新资源:

    oc apply -f <kafka_configuration_file>
    Copy to Clipboard Toggle word wrap
  3. 创建新主题或将现有分区重新分配给新磁盘。

    提示

    Cruise Control 是一个重新分配分区的有效工具。要执行 intra-broker 磁盘平衡,您可以在 KafkaRebalance.spec 下将 rebalanceDisk 设置为 true

9.12.7. 从 JBOD 存储中删除卷

此流程描述了如何从配置为使用 JBOD 存储的 Kafka 集群中删除卷。它不能应用到配置为使用任何其他存储类型的 Kafka 集群。JBOD 存储始终必须包含至少一个卷。

重要

为了避免数据丢失,您必须在删除卷前移动所有分区。

先决条件

  • 一个 OpenShift 集群
  • 正在运行的 Cluster Operator
  • 具有两个或多个卷的 JBOD 存储的 Kafka 集群

流程

  1. 从您要删除的磁盘中重新分配所有分区。分区中的任何数据仍被分配给要删除的磁盘。

    提示

    您可以使用 kafka-reassign-partitions.sh 工具重新分配分区。

  2. 编辑 Kafka 资源中的 spec.kafka.storage.volumes 属性。从 volumes 阵列中删除一个或多个 。例如,使用 ids 12 删除卷:

    apiVersion: kafka.strimzi.io/v1beta2
    kind: Kafka
    metadata:
      name: my-cluster
    spec:
      kafka:
        # ...
        storage:
          type: jbod
          volumes:
          - id: 0
            type: persistent-claim
            size: 100Gi
            deleteClaim: false
        # ...
      zookeeper:
        # ...
    Copy to Clipboard Toggle word wrap
  3. 创建或更新资源:

    oc apply -f <kafka_configuration_file>
    Copy to Clipboard Toggle word wrap

9.12.8. 分层存储(早期访问)

分层存储引入了一种灵活的方法,用于管理 Kafka 数据,其中日志片段被移到单独的存储系统。例如,您可以在代理中使用块存储,以频繁访问块存储中的数据,从块存储中卸载旧或更频繁的数据,到更经济、可扩展的远程存储解决方案,如 Amazon S3,而不影响数据可访问性和持久性。

警告

分层存储是一个早期访问 Kafka 功能,它也可用于 Apache Kafka 的流。由于其 当前限制,不建议在生产环境中使用。

分层存储需要实现 Kafka 的 RemoteStorageManager 接口来处理 Kafka 和远程存储系统之间的通信,这通过配置 Kafka 资源启用。在启用了自定义分层存储时,Apache Kafka 的 Streams 使用 Kafka 的 TopicBasedRemoteLogMetadataManager for Remote Log Metadata Management (RLMM)。RLMM 管理与远程存储相关的元数据。

要使用自定义分层存储,请执行以下操作:

  • 通过构建自定义容器镜像,在 Apache Kafka 镜像的 Streams 中包括 Kafka 的分层存储插件。该插件必须为由 Apache Kafka 管理的 Kafka 集群提供必要的功能,才能与分层存储解决方案交互。
  • 使用 Kafka 资源中分层存储属性为 分层存储 配置 Kafka。指定自定义 RemoteStorageManager 实现的类名称和路径,以及任何其他配置。
  • 如果需要,指定特定于 RLMM 的分层存储配置。

Kafka 的自定义分层存储配置示例

apiVersion: kafka.strimzi.io/v1beta2
kind: Kafka
metadata:
  name: my-cluster
spec:
  kafka:
    tieredStorage:
      type: custom 
1

      remoteStorageManager: 
2

        className: com.example.kafka.tiered.storage.s3.S3RemoteStorageManager
        classPath: /opt/kafka/plugins/tiered-storage-s3/*
        config:
          storage.bucket.name: my-bucket 
3

          # ...
    config:
      rlmm.config.remote.log.metadata.topic.replication.factor: 1 
4

  # ...
Copy to Clipboard Toggle word wrap

1
类型 必须设置为 自定义
2
自定义 RemoteStorageManager 实现的配置,包括类名称和路径。
3
配置传递给自定义 RemoteStorageManager 实现,Apache Kafka 的 Streams 会自动使用 rsm.config 前缀。
4
分层存储配置以传递到 RLMM,这需要 rlmm.config. 前缀。有关分层存储配置的更多信息,请参阅 Apache Kafka 文档
返回顶部
Red Hat logoGithubredditYoutubeTwitter

学习

尝试、购买和销售

社区

关于红帽文档

通过我们的产品和服务,以及可以信赖的内容,帮助红帽用户创新并实现他们的目标。 了解我们当前的更新.

让开源更具包容性

红帽致力于替换我们的代码、文档和 Web 属性中存在问题的语言。欲了解更多详情,请参阅红帽博客.

關於紅帽

我们提供强化的解决方案,使企业能够更轻松地跨平台和环境(从核心数据中心到网络边缘)工作。

Theme

© 2025 Red Hat