标准经纪商的最佳实践 - Amazon Managed Streaming for Apache Kafka
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

标准经纪商的最佳实践

本主题概述使用 Amazon MSK 时应遵循的一些最佳实践。有关 Amazon MSK 复制器最佳实践的信息,请参阅使用 MSK 复制器的最佳实践

客户端注意事项

应用程序的可用性和性能不仅取决于服务器端设置,还取决于客户端设置。

  • 配置您的客户端以实现高可用性。在 Apache Kafka 这样的分布式系统中,确保高可用性对于维护可靠且容错的消息传递基础设施至关重要。代理商将因计划内和计划外事件(例如升级、补丁、硬件故障和网络问题)而下线。Kafka 集群可以容忍代理离线,因此 Kafka 客户端也必须妥善处理代理失效转移。请查看有关的完整详细信息Apache Kafka 客户端的最佳实践

  • 确保客户端连接字符串至少包含来自每个可用区的一个代理。在客户端的连接字符串中具有多个代理,则可在特定代理脱机进行更新时实现失效转移。有关如何获取具有多个代理的连接字符串的信息,请参阅获取 Amazon MSK 集群的引导代理

  • 运行性能测试以验证您的客户端配置是否允许您实现性能目标。

服务器端注意事项

正确调整集群规模:每个标准代理的分区数

下表显示了每个标准代理的推荐分区数量(包括领导副本和跟随者副本)。建议的分区数并未强制执行,对于跨所有已配置的主题分区发送流量的场景,这是最佳实践。

代理大小 建议的每个代理的分区数量(包括领导副本和跟随者副本)。 支持更新操作的最大分区数
kafka.t3.small 300 300
kafka.m5.largekafka.m5.xlarge 1000 1500
kafka.m5.2xlarge 2000 3000
kafka.m5.4xlargekafka.m5.8xlargekafka.m5.12xlargekafka.m5.16xlargekafka.m5.24xlarge 4000 6000
kafka.m7g.largekafka.m7g.xlarge 1000 1500
kafka.m7g.2xlarge 2000 3000
kafka.m7g.4xlargekafka.m7g.8xlargekafka.m7g.12xlargekafka.m7g.16xlarge 4000 6000

如果您有高分区、低吞吐量的用例,其中分区数较高,但没有在所有分区之间发送流量,则可以为每个代理打包更多分区,前提是您已执行了足够的测试和性能测试,以验证分区数越高的群集是否保持健康。如果每个代理的分区数超过允许的最大值,并且您的集群过载,则您将无法执行以下操作:

  • 更新集群配置

  • 将集群更新为较小的代理大小

  • 将 Amazon Secrets Manager 密钥与具有 SASL/SCRAM 身份验证的集群相关联

大量分区还可能导致 Prometheus 抓取 CloudWatch 和抓取时缺少 Kafka 指标。

有关选择分区数的指导,请参阅 Apache Kafka 支持每个集群 20 万个分区。我们还建议您执行自己的测试,以确定适合您代理的大小。有关不同代理大小的更多信息,请参阅亚马逊 MSK 经纪商类型

调整集群规模:每个集群的标准代理数量

要为您的 MSK 预配置集群确定合适的标准代理数量并了解成本,请参阅 MSK 规模和定价电子表格。此电子表格估算了 MSK 预配置集群的大小,以及 Amazon MSK 与类似的、 EC2基于自我管理的 Apache Kafka 集群相比,Amazon MSK 的相关成本。有关电子表格中的输入参数的更多信息,请将鼠标指针悬停在参数描述的上方。本表提供的估计值是保守的,为新的 MSK 预配置集群提供了起点。集群的性能、大小和成本取决于您的用例,建议您通过实际测试进行验证。

要了解底层基础架构如何影响 Apache Kafka 性能,请参阅大数据博客中的调整您的 Apache Kafka 集群规模以优化性能和成本的最佳实践。 Amazon 这篇博客文章提供了有关如何调整集群大小以满足吞吐量、可用性和延迟要求的信息。它还提供了问题的答案,例如何时应向扩展还是向外扩展,以及有关如何持续验证生产集群规模的指导。有关基于分层存储的集群的信息,请参阅使用 Amazon MSK 分层存储运行生产工作负载的最佳实践

优化 m5.4xl、m7g.4xl 或更大实例的集群吞吐量

使用 m5.4xl、m7g.4xl 或更大的实例时,您可以通过调整 num.io.threads 和 num.network.threads 配置来优化 MSK 预配置的集群吞吐量。

num.io.threads 是标准代理用于处理请求的线程数。添加更多线程(不超过实例大小支持的 CPU 核心数量)有助于提高集群的吞吐量。

num.network.threads 是标准代理用于接收所有传入请求和返回响应的线程数。网络线程将传入请求放在请求队列中,以供 io.threads 处理。将 num.network.threads 设置为实例大小支持的 CPU 核心数量的一半,即可充分使用新的实例大小。

重要

如果不先增加 num.io.threads,请勿增加 num.network.threads,因为这可能会导致与队列饱和相关的拥塞。

推荐设置
实例大小 num.io.threads 的推荐值 num.network.threads 的推荐值

m5.4xl

16

8

m5.8xl

32

16

m5.12xl

48

24

m5.16xl

64

32

m5.24xl

96

48

m7g.4xlarge

16

8

m7g.8xlarge

32

16

m7g.12xlarge

48

24

m7g.16xlarge

64

32

使用最新的 Kafka AdminClient 来避免主题 ID 不匹配问题

当您使用低于 2.8.0 的 Kafka 版本和标志--zookeeper,为使用 Kafka AdminClient 版本 2.8.0 或更高版本的 MSK 预配置集群增加或重新分配主题分区时,主题的 ID 会丢失(错误:与分区的主题 ID 不匹配)。请注意,--zookeeper 标志在 Kafka 2.5 中已弃用,并从 Kafka 3.0 开始删除。请参阅 Upgrading to 2.5.0 from any version 0.8.x through 2.4.x

为防止主题 ID 不匹配,请使用 Kafka 客户端版本 2.8.0 或更高版本进行 Kafka 管理员操作。或者,2.5 及更高版本的客户端可以使用 --bootstrap-servers 标志代替 --zookeeper 标志。

构建高度可用的集群

使用以下建议,以便在更新(例如更新代理大小或 Apache Kafka 版本时)或 Amazon MSK 更换代理时,您的 MSK 预配置集群可以保持高可用性。

  • 设置三可用区集群。

  • 确保复制因子(RF)至少为 3。请注意,在滚动更新期间,RF 为 1 可能会导致分区离线;而 RF 为 2 可能会导致数据丢失。

  • 将最小同步副本数 (minISR) 设置为最多 RF - 1。minISR 等于 RF 可能会阻止在滚动更新期间生成到集群。当一个副本处于脱机状态时,minISR 为 2 使三向复制主题可用。

监控 CPU 使用率

Amazon MSK 强烈建议您将经纪商的 CPU 使用率(定义为CPU User + CPU System)保持在 60% 以下。这样可以确保您的集群保留足够的 CPU 余量来处理操作事件,例如代理故障、修补和滚动升级。

必要时,Apache Kafka 可以在集群中的代理之间重新分配 CPU 负载。例如,当 Amazon MSK 检测到代理故障并从中恢复过来时,它会执行自动维护,例如修补。同样,当用户请求更改代理规模或版本升级时,Amazon MSK 会启动滚动工作流程,一次使一个代理下线。当具有领导分区的代理离线时,Apache Kafka 会重新分配分区领导权,以将工作重新分配给集群中的其他代理。通过遵循此最佳实践,可以确保有足够的 CPU 余量来容忍这些操作事件。

注意

在监控 CPU 使用率时,请注意总的 CPU 使用率包括CPU User和以上CPU System。其他类别,例如iowaitirqsoftirq、和steal,也会影响整体 CPU 活动。因此,CPU 空闲并不总是等于100% - CPU User - CPU System

您可以使用 Amazon CloudWatch 指标数学来创建复合指标 (CPU User + CPU System),并将警报设置为在平均使用量超过 60% 时触发。触发后,请考虑使用以下选项之一扩展集群:

  • 选项 1(推荐):将您的代理大小更新为下一个较大的大小。例如,如果当前大小为 kafka.m5.large,则更新集群以使用 kafka.m5.xlarge。请记住,当您更新集群中的代理大小时,Amazon MSK 会以滚动方式使代理离线,并暂时将分区领导权重新分配给其他代理。每个代理的规模更新通常需要 10-15 分钟。

  • 选项 2:如果主题中的所有消息都是从使用轮询写入的生成器那里摄取的(换句话说,消息没有密钥,顺序对使用器来说并不重要),请通过添加代理来扩展集群。还要向吞吐量最高的现有主题添加分区。接下来,使用 kafka-topics.sh --describe 来确保将新添加的分区分配给新代理。与前一个选项相比,此选项的主要优点是您可以更精细地管理资源和成本。此外,如果 CPU 负载明显超过 60%,则可使用此选项,因为这种形式的扩展通常不会导致现有代理的负载增加。

  • 选项 3:通过添加代理来扩展 MSK Provisioned 集群,然后使用名为的分区重新分配工具重新分配现有分区。kafka-reassign-partitions.sh但是,如果您使用此选项,则在重新分配分区后,集群将需要花费资源将数据从一个代理复制到另一个代理。与前两个选项相比,这可能会在一开始显著增加集群的负载。因此,Amazon MSK 不建议在 CPU 利用率高于 70% 时使用此选项,因为复制会导致额外的 CPU 负载和网络流量。仅当前两个选项不可行时,Amazon MSK 才建议使用此选项。

其他建议:

  • 作为负载分配的代理,监控每个代理的 CPU 总利用率。如果代理的 CPU 利用率一直不均衡,则可能表明集群内的负载分布不均。我们建议使用 C ruise Control 通过分区分配持续管理负载分配。

  • 监控生成和使用延迟。生成和使用延迟会随着 CPU 利用率呈线性增加。

  • JMX 抓取间隔:如果您使用 Prometheus 功能启用开源监控系统,则建议您为 Prometheus 主机配置 (prometheus.yml) 使用 60 秒或更长的抓取间隔 (scrape_interval: 60s)。降低抓取间隔可能会导致集群上的 CPU 使用率过高。

监控磁盘空间

为避免存储消息的磁盘空间不足,请创建KafkaDataLogsDiskUsed监控指标的 CloudWatch 警报。当此指标的值达到或超过 85% 时,请执行下列一项或多项操作:

有关如何设置和使用警报的信息,请参阅使用 Amazon CloudWatch 警报。有关 Amazon MSK 指标的完整列表,请参阅监控 Amazon MSK 预配置的集群

调整数据保留参数

使用消息不会将其从日志中删除。要定期释放磁盘空间,您可以明确指定一个保留时间段,即消息在日志中保留的时间。您也可以指定保留日志大小。当达到保留时间段或保留日志大小时,Apache Kafka 会开始从日志中删除非活动段。

要在集群级别指定保留策略,请设置以下一个或多个参数:log.retention.hourslog.retention.minuteslog.retention.mslog.retention.bytes。有关更多信息,请参阅 自定义 Amazon MSK 配置

您也可以在主题级别指定保留参数:

  • 要为每个主题指定一个保留时间段,请使用以下命令。

    kafka-configs.sh --bootstrap-server $bs --alter --entity-type topics --entity-name TopicName --add-config retention.ms=DesiredRetentionTimePeriod
  • 要为每个主题指定一个保留日志大小,请使用以下命令。

    kafka-configs.sh --bootstrap-server $bs --alter --entity-type topics --entity-name TopicName --add-config retention.bytes=DesiredRetentionLogSize

您在主题级别指定的保留参数优先于集群级别参数。

在不正常关闭后加快日志恢复

在不正常关闭后,代理可能需要一段时间才能重新启动,因为它需进行日志恢复。默认情况下,Kafka 仅对每个日志目录使用一个线程来执行此恢复。例如,如果您有成千上万个分区,则日志恢复可能需要数个小时才能完成。为加快日志恢复,建议使用配置属性 num.recovery.threads.per.data.dir 增加线程数量。您可以将它设置为 CPU 核心的数量。

监控 Apache Kafka 内存

建议您监控 Apache Kafka 使用的内存。否则,集群可能会变得不可用。

要确定 Apache Kafka 使用了多少内存,您可以监控 HeapMemoryAfterGC 指标。HeapMemoryAfterGC 是垃圾回收后使用的总堆内存百分比。我们建议您创建一个 CloudWatch 警报,当HeapMemoryAfterGC增幅超过 60% 时会采取行动。

可用于减少内存使用的步骤会有所不同,具体取决于您配置 Apache Kafka 的方式。例如,如果您使用事务性消息传递,则可以将 Apache Kafka 配置中的 transactional.id.expiration.ms 值从 604800000 毫秒减少到 86400000 毫秒(从 7 天减少到 1 天)。这减少了每个事务的内存占用。

请勿添加非 MSK 代理

对于 ZooKeeper基于 MSK 预配置的集群,如果您使用 Apache ZooKeeper 命令添加代理,则这些代理不会被添加到您的 MSK 预配置集群中,并且您的 Apache ZooKeeper 将包含有关该集群的不正确信息。这可能会导致丢失数据。有关支持的 MSK 预配置集群操作,请参阅。亚马逊 MSK 的主要功能和概念

启用传输中加密

有关传输中加密以及如何启用此加密的信息,请参阅Amazon MSK 传输中加密

重新分配分区

要将分区移动到同一 MSK Provisioned 集群上的不同代理,您可以使用名为的分区重新分配工具。kafka-reassign-partitions.sh为了安全操作,我们建议您在一次kafka-reassign-partitions调用中重新分配的分区不要超过 10 个。例如,在添加新代理以扩展集群或移动分区以移除代理之后,您可以通过将分区重新分配给新代理来重新平衡该集群。有关如何向 MSK 预配置集群添加代理的信息,请参阅。扩展 Amazon MSK 集群中的代理数量有关如何从 MSK 预配置集群中移除代理的信息,请参阅。从 Amazon MSK 集群中移除代理有关分区重新分配工具的信息,请参阅 Apache Kafka 文档中的扩展集群