调整 Apache Kafka 集群规模以优化性能和成本的最佳实践
调整 Apache Kafka 集群规模以优化性能和成本的最佳实践
本文翻译自AWS博客文章,原文见参考文献,作者为Steffen Hausmann,AWS的首席流架构师。文章从多角度分析如何确定集群规模以最大化成本和性能效益,对于集群部署与应用调优等方面具有极大价值。
Apache Kafka 以其针对各种用例进行优化的性能和可调性而闻名。 但有时要找到既能满足您的特定性能要求又能最大限度地降低基础设施成本的正确基础设施配置可能具有挑战性。
这篇文章解释了底层基础设施如何影响 Apache Kafka 的性能。 我们讨论了有关如何调整集群大小以满足吞吐量、可用性和延迟要求的策略。 在此过程中,我们会回答诸如“什么时候纵向扩展和横向扩展有意义?”之类的问题。 我们以如何持续验证生产集群的大小为结尾。
我们使用性能测试来说明和解释不同策略对集群规模的影响和权衡。 但与往常一样,重要的是不要盲目相信您碰巧在互联网上找到的基准。 因此,我们不仅展示了如何重现结果,还解释了如何使用性能测试框架针对您的特定工作负载特征运行您自己的测试。
调整 Apache Kafka 集群的大小
从基础架构的角度来看,集群最常见的资源瓶颈是网络吞吐量、存储吞吐量以及broker与使用网络附加存储(例如 Amazon Elastic Block Store (Amazon EBS))的broker存储后端之间的网络吞吐量。
帖子的其余部分解释了集群的持续吞吐量限制如何不仅取决于broker的存储和网络吞吐量限制,还取决于broker和消费者组的数量以及复制因子 r。 给定特定集群的基础设施特征,我们推导出理论持续吞吐量限制 tcluster 的以下公式(在本文中称为公式 1):
max(tcluster) <= min{
max(tstorage) * #brokers/r,
max(tEBSnetwork) * #brokers/r,
max(tEC2network) * #brokers/(#consumer groups + r-1)
}
对于生产集群,最佳实践是将实际吞吐量设定为理论持续吞吐量限制的 80%。 例如,考虑一个具有 m5.12xlarge broker的三节点集群,复制因子为 3,EBS 卷的基准吞吐量为 1000 MB/秒,并且两个消费者组从主题的提示中消费。 考虑到所有这些参数,集群吸收的持续吞吐量应该达到 800 MB/秒。
但是,这种吞吐量计算只是为针对高吞吐量场景优化的工作负载提供上限。 无论您如何配置主题以及从这些主题读取和写入这些主题的客户端,集群都无法吸收更多的吞吐量。 对于具有不同特征的工作负载,例如对延迟敏感或计算密集型的工作负载,集群在满足这些额外要求的同时可以吸收的实际吞吐量通常较小。
要为您的工作负载找到正确的配置,您需要从您的用例回溯并确定适当的吞吐量、可用性、持久性和延迟要求。 然后,根据您的吞吐量、持久性和存储要求,使用公式 1 获得集群的初始大小。 通过运行性能测试验证此初始集群大小,然后微调集群大小、集群配置和客户端配置以满足您的其他要求。 最后,为生产集群添加额外的容量,这样即使集群以降低的容量运行,它们仍然可以摄取预期的吞吐量,例如,在维护、扩展或broker丢失期间。 根据您的工作负载,您甚至可以考虑添加足够的备用容量来承受影响整个可用区所有broker的事件。
该帖子的其余部分将更深入地探讨集群大小调整的各个方面。 最重要的方面如下:
- 通常需要在横向扩展或纵向扩展之间做出选择,以提高集群的吞吐量和性能。小型broker为您提供更小的容量增量,并且在它们变得不可用时具有更小的爆炸半径。但是,拥有许多小型broker会增加需要对broker进行滚动更新才能完成的操作所需的时间,并增加失败的可能性。
- 生产者发送到集群的所有流量都保存在磁盘上。因此,存储卷的底层吞吐量可能成为集群的瓶颈。在这种情况下,在可能的情况下增加卷吞吐量或向集群添加更多卷是有意义的。
- 保存在 EBS 卷上的所有数据都会遍历网络。 Amazon EBS 优化实例为 Amazon EBS I/O 提供专用容量,但专用 Amazon EBS 网络仍可能成为集群的瓶颈。在这种情况下,扩展broker是有意义的,因为更大的broker具有更高的 Amazon EBS 网络吞吐量。
- 从集群读取的消费者群体越多,通过代理的 Amazon Elastic Compute Cloud (Amazon EC2) 网络流出的数据就越多。根据代理类型和大小,Amazon EC2 网络可能成为集群的瓶颈。在这种情况下,扩展代理是有意义的,因为更大的代理具有更高的 Amazon EC2 网络吞吐量。
- 对于 p99 放置延迟,启用集群内加密会对性能产生重大影响。与较小的代理相比,扩大集群的代理可以大大减少 p99 放置延迟。
- 当消费者落后或需要重新处理历史数据时,请求的数据可能不再驻留在内存中,代理需要从存储卷中取数据。这会导致非顺序 I/O 读取。使用 EBS 卷时,它还会导致卷的额外网络流量。使用具有更多内存的更大代理或启用压缩可以减轻这种影响。
- 使用集群的突发功能是一种非常强大的方式来吸收突然的吞吐量峰值,而无需扩展集群,这需要时间来完成。突发容量也有助于响应操作事件。例如,当 broker 正在进行维护或需要在集群内重新平衡分区时,它们可以利用突发性能更快地完成操作。
- 监视或警告与基础设施相关的重要集群指标,例如 BytesInPerSec、ReplicationBytesInPerSec、BytesOutPerSec 和 ReplicationBytesOutPerSec,以便在当前集群大小不再适合当前集群大小时收到通知。
帖子的其余部分提供了更多背景信息并解释了这些建议背后的原因。
了解 Apache Kafka 性能瓶颈
在我们开始从基础架构的角度讨论性能瓶颈之前,让我们重新审视数据在集群中的流动方式。
对于这篇文章,我们假设生产者和消费者的行为良好并符合最佳实践,除非明确说明不同。 例如,我们假设生产者平均平衡代理之间的负载,代理托管相同数量的分区,有足够的分区来摄取吞吐量,消费者直接从流的末端消费,等等。 broker接收相同的负载并执行相同的工作。 因此,我们只关注以下集群内数据流图中的 Broker 1。
生产者将 tcluster 的总吞吐量发送到集群中。 由于流量在代理之间均匀分布,broker 1 接收到传入吞吐量 tcluster/3。 复制因子为 3 时,broker 1 将其直接接收的流量复制到其他两个代理(蓝线)。 同样,代理 1 从两个代理(红线)接收复制流量。 每个消费者组消费直接产生到 Broker 1 的流量(绿线)。 所有从生产者到达 Broker 1 的流量和来自其他broker的复制流量最终都会持久保存到附加到broker的存储卷中。
因此,存储卷和代理网络的吞吐量都与整个集群的吞吐量紧密相关,值得仔细研究。
存储后端吞吐量特征
Apache Kafka 被设计为在将数据写入磁盘时利用大型顺序 I/O 操作。 生产者只会将数据附加到日志的顶端,从而导致顺序写入。 此外,Apache Kafka 不会同步刷新到磁盘。 相反,Apache Kafka 正在写入页面缓存,让操作系统将页面刷新到磁盘。 这会导致大量顺序 I/O 操作,从而优化磁盘吞吐量。
对于许多实际用途,broker可以驱动卷的全部吞吐量并且不受 IOPS 限制。 我们假设消费者正在阅读主题的提示。 这意味着 EBS 卷的性能受吞吐量限制而不是 I/O 限制,并且读取是从页面缓存提供的。
存储后端的入口吞吐量取决于生产者直接发送给broker的数据加上broker从其对等方接收的复制流量。 对于产生到 tcluster 集群和复制因子 r 的聚合吞吐量,broker存储接收的吞吐量如下:
tstorage = tcluster/#brokers + tcluster/#brokers * (r-1)
= tcluster/#brokers * r
因此,整个集群的持续吞吐量限制受以下约束:
max(tcluster) <= max(tstorage) * #brokers/r
AWS 为块存储提供不同的选项:实例存储和 Amazon EBS。 实例存储位于物理连接到主机的磁盘上,而 Amazon EBS 是网络附加存储。
实例存储附带的实例系列可实现高 IOPS 和磁盘吞吐量。 例如,Amazon EC2 I3 实例包括基于 NVMe SSD 的实例存储,针对低延迟、极高的随机 I/O 性能和高顺序读取吞吐量进行了优化。 但是,卷与brokers有关。 它们的特性,尤其是它们的大小,仅取决于实例系列,而卷大小无法调整。 此外,当broker发生故障需要更换时,存储卷将丢失。 然后,替换broker需要从其他代理复制数据。 除了broker丢失导致的容量减少之外,此复制还会导致集群上的额外负载。
相比之下,EBS 卷的特性可以在使用时进行调整。 您可以使用这些功能随着时间的推移自动扩展代理存储,而不是为峰值配置存储或添加额外的代理。 一些 EBS 卷类型,例如 gp3、io2 和 st1,还允许您调整现有卷的吞吐量和 IOPS 特征。 此外,EBS 卷的生命周期独立于代理——如果代理发生故障并需要更换,EBS 卷可以重新附加到替换代理。 这避免了大多数其他所需的复制流量。
因此,对于许多常见的 Apache Kafka 工作负载,使用 EBS 卷通常是一个不错的选择。 它们提供了更大的灵活性并支持更快的扩展和恢复操作。
Amazon EBS 吞吐量特征
当使用 Amazon EBS 作为存储后端时,有多种卷类型可供选择。不同卷类型的吞吐量特性介于 128 MB/秒和 4000 MB/秒之间(有关更多信息,请参阅 Amazon EBS 卷类型)。您甚至可以选择将多个卷附加到一个代理,以增加吞吐量,使其超过单个卷可以提供的吞吐量。
但是,Amazon EBS 是网络附加存储。代理写入 EBS 卷的所有数据都需要遍历网络到达 Amazon EBS 后端。新一代实例系列,如 M5 系列,是 Amazon EBS 优化实例,具有用于 Amazon EBS I/O 的专用容量。但是吞吐量和 IOPS 存在限制,这取决于实例的大小,而不仅仅是卷的大小。 Amazon EBS 的专用容量为更大的实例提供了更高的基准吞吐量和 IOPS。容量介于 81 MB/秒和 2375 MB/秒之间。有关更多信息,请参阅支持的实例类型。
当使用 Amazon EBS 进行存储时,我们可以调整集群持续吞吐量限制的公式以获得更严格的上限:
max(tcluster) <= min{
max(tstorage) * #brokers/r,
max(tEBSnetwork) * #brokers/r
}
Amazon EC2 网络吞吐量
到目前为止,我们只考虑了 EBS 卷的网络流量。 但是复制和消费者群体也会导致 Amazon EC2 网络流量流出代理。 生产者发送到代理的流量被复制到 r-1 个代理。 此外,每个消费者组都会读取代理摄取的流量。 因此,整体出网流量如下:
tEC2network = tcluster/#brokers * #consumer groups + tcluster/#brokers * (r–1)
= tcluster/#brokers * (#consumer groups + r-1)
将此流量考虑在内,最终为我们提供了集群持续吞吐量限制的合理上限,我们已经在等式 1 中看到:
max(tcluster) <= min{
max(tstorage) * #brokers/r,
max(tEBSnetwork) * #brokers/r,
max(tEC2network) * #brokers/(#consumer groups + r-1)
}
对于生产工作负载,我们建议将工作负载的实际吞吐量保持在由该公式确定的理论持续吞吐量限制的 80% 以下。 此外,我们假设所有发送到集群中的数据生产者最终都会被至少一个消费者组读取。 当消费者数量大于或等于 1 时,流出代理的 Amazon EC2 网络流量始终高于流入代理的流量。 因此,我们可以忽略进入代理的数据流量作为潜在的瓶颈。
通过公式 1,我们可以验证具有给定基础架构的集群是否可以在理想条件下吸收我们的工作负载所需的吞吐量。 有关 m5.8xlarge 和更大实例的 Amazon EC2 网络带宽的更多信息,请参阅 Amazon EC2 实例类型。 您还可以在同一页面上找到 m5.4xlarge 实例的 Amazon EBS 带宽。 较小的实例对 Amazon EC2 网络带宽和 Amazon EBS 带宽使用基于信用的系统。 对于 Amazon EC2 网络基准带宽,请参阅网络性能。 对于 Amazon EBS 基准带宽,请参阅支持的实例类型。
调整集群规模以优化性能和成本
那么,我们从中得到了什么?最重要的是,请记住,这些结果仅表示集群在理想条件下的持续吞吐量限制。这些结果可以为您提供集群预期持续吞吐量限制的一般数字。但是您必须运行自己的实验来针对您的特定工作负载和配置验证这些结果。
然而,我们可以从这个吞吐量估计中得出一些结论:添加代理会增加持续的集群吞吐量。同样,降低复制因子会增加持续的集群吞吐量。如果 Amazon EC2 网络成为瓶颈,添加多个消费者组可能会降低持续的集群吞吐量。
让我们运行几个实验来获得关于实际持续集群吞吐量的经验数据,这些数据也考虑了生产者放置延迟。对于这些测试,我们将吞吐量保持在建议的集群持续吞吐量限制的 80% 以内。在运行您自己的测试时,您可能会注意到集群甚至可以提供比我们展示的更高的吞吐量。
测量 Amazon MSK 集群吞吐量和放置延迟
为了创建实验的基础设施,我们使用 Amazon Managed Streaming for Apache Kafka (Amazon MSK)。 Amazon MSK 预置和管理由 Amazon EBS 存储支持的高度可用的 Apache Kafka 集群。 因此,如果由 EBS 卷支持,以下讨论也适用于尚未通过 Amazon MSK 预配置的集群。
这些实验基于 Apache Kafka 发行版中包含的 kafka-producer-perf-test.sh 和 kafka-consumer-perf-test.sh 工具。 测试使用六个生产者和两个消费者组,每个消费者组有六个消费者,它们同时从集群读取和写入。 如前所述,我们确保客户端和brokers根据最佳实践表现良好:生产者平均平衡brokers之间的负载,brokers托管相同数量的分区,消费者直接从流的顶端消费,生产者和消费者数量足够,这样它们就不会成为测量中的瓶颈,等等。
我们使用将代理部署到三个可用区的集群。 此外,replication 设置为 3,acks 设置为 all,以实现持久化在集群中的数据的高持久性。 我们还配置了 256 kB 或 512 kB 的 batch.size 并将 linger.ms 设置为 5 毫秒,这减少了摄取小批量记录的开销,从而优化了吞吐量。 分区数根据代理大小和集群吞吐量进行调整。
大于 m5.2xlarge 的代理的配置已根据 Amazon MSK 开发人员指南的指导进行了调整。 特别是在使用预配置吞吐量时,必须相应地优化集群配置。
下图比较了具有不同代理大小的三个集群的放置延迟。 对于每个集群,生产者正在运行大约十几个具有不同吞吐量配置的单独性能测试。 最初,生产者在集群中产生 16 MB/秒的组合吞吐量,并逐渐增加每个单独测试的吞吐量。 每个单独的测试运行 1 小时。 对于具有突发性能特征的实例,信用在开始实际性能测量之前被耗尽。
对于存储超过 334 GB 的代理,我们可以假设 EBS 卷的基准吞吐量为 250 MB/秒。 对于不同的代理大小,Amazon EBS 网络基准吞吐量分别为 81.25、143.75、287.5 和 593.75 MB/秒(有关更多信息,请参阅支持的实例类型)。 Amazon EC2 网络基准吞吐量为 96、160、320 和 640 MB/秒(有关更多信息,请参阅网络性能)。 请注意,这仅考虑了持续吞吐量; 我们将在后面的部分讨论突发性能。
对于具有复制 3 和两个消费者组的三节点集群,根据公式 1 推荐的入口吞吐量限制如下。
尽管 m5.4xlarge 代理的 vCPU 和内存数量是 m5.2xlarge 代理的两倍,但在将代理从 m5.2xlarge 扩展到 m5.4xlarge 时,集群持续吞吐量限制几乎没有增加。 这是因为在这种配置下,代理使用的 EBS 卷成为瓶颈。 请记住,我们假设这些卷的基准吞吐量为 250 MB/秒。 对于三节点集群和复制因子 3,每个代理需要向 EBS 卷写入与发送到集群本身相同的流量。 并且由于 EBS 卷的 80% 基准吞吐量为 200 MB/秒,因此建议使用 m5.4xlarge 代理的集群的持续吞吐量限制为 200 MB/秒。
下一节将介绍如何使用预配置吞吐量来增加 EBS 卷的基准吞吐量,从而增加整个集群的持续吞吐量限制。
通过预配置的吞吐量增加broker吞吐量
从前面的结果中,您可以看到,从纯吞吐量的角度来看,使用默认集群配置将代理大小从 m5.2xlarge 增加到 m5.4xlarge 几乎没有什么好处。 代理使用的 EBS 卷的基准吞吐量限制了它们的吞吐量。 但是,Amazon MSK 最近推出了预置存储吞吐量高达 1000 MB/秒的功能。 对于自我管理的集群,您可以使用 gp3、io2 或 st1 卷类型来实现类似的效果。 根据代理大小,这可以显着提高整体集群吞吐量。
下图比较了不同代理大小和不同预配吞吐量配置的集群吞吐量和放置延迟。
对于具有复制 3 和两个消费者组的三节点集群,根据公式 1 推荐的入口吞吐量限制如下。
为给定的工作负载精心选择了配置的吞吐量配置。 有两个消费者组从集群中消费,将 m4.4xlarge 代理的配置吞吐量增加到超过 480 MB/秒没有意义。 Amazon EC2 网络(而非 EBS 卷吞吐量)将建议的集群持续吞吐量限制限制为 384 MB/秒。 但对于具有不同数量消费者的工作负载,进一步增加或减少配置的吞吐量配置以匹配 Amazon EC2 网络的基准吞吐量是有意义的。
横向扩展以增加集群写入吞吐量
横向扩展集群自然会增加集群吞吐量。 但这对性能和成本有何影响? 让我们比较两个不同集群的吞吐量:三节点 m5.4xlarge 和六节点 m5.2xlarge 集群,如下图所示。 m5.4xlarge 集群的存储大小已经过调整,因此两个集群具有相同的总存储容量,因此这些集群的成本相同。
六节点集群的吞吐量几乎是三节点集群的两倍,并且大大降低了 p99 放置延迟。 仅查看集群的入口吞吐量,如果您需要超过 200 MB/秒的吞吐量,则横向扩展比纵向扩展更有意义。 下表总结了这些建议。
在这种情况下,我们也可以使用预配置的吞吐量来增加集群的吞吐量。 例如,将上图中六节点 m5.2xlarge 集群的持续吞吐量限制与前面示例中配置吞吐量的三节点 m5.4xlarge 集群的持续吞吐量限制进行比较。 两个集群的持续吞吐量限制是相同的,这是由相同的 Amazon EC2 网络带宽限制引起的,该限制通常与代理大小成比例增长。
向上扩展以增加集群读取吞吐量
从集群中读取的消费者群体越多,通过代理的 Amazon EC2 网络流出的数据就越多。 较大的代理具有更高的网络基线吞吐量(高达 25 Gb/秒),因此可以支持更多的消费者群体从集群中读取数据。
下图比较了三节点 m5.2xlarge 集群的不同数量的消费者组的延迟和吞吐量变化情况。
如此图所示,增加从集群读取的消费者组数量会降低其持续吞吐量限制。 消费者组从集群中读取的消费者越多,需要通过 Amazon EC2 网络从代理传出的数据就越多。 下表总结了这些建议。
代理大小决定了 Amazon EC2 网络吞吐量,除了按比例扩大外,没有办法增加它。 因此,要扩展集群的读取吞吐量,您需要扩展代理或增加代理的数量。
平衡broker 规模和broker 数量
在调整集群大小时,您通常可以选择横向扩展或纵向扩展以提高集群的吞吐量和性能。 假设相应地调整存储大小,这两个选项的成本通常是相同的。 那么什么时候应该横向扩展或纵向扩展呢?
使用较小的代理允许您以较小的增量扩展容量。 Amazon MSK 强制代理在所有已配置的可用区之间保持均衡。 因此,您只能添加数量为可用区数倍数的代理。 例如,如果您将三个代理添加到具有预置吞吐量的三节点 m5.4xlarge 集群,则建议的持续集群吞吐量限制增加 100%,从 384 MB/秒增加到 768 MB/秒。 但是,如果将三个代理添加到六节点 m5.2xlarge 集群,建议的集群吞吐量限制将增加 50%,从 384 MB/秒增加到 576 MB/秒。
大型代理太少也会增加爆炸半径,以防单个代理因维护或底层基础设施故障而停机。例如,对于三节点集群,单个代理对应集群容量的 33%,而对于六节点集群,它仅为 17%。根据最佳实践配置集群时,您已经添加了足够的备用容量,不会在这些操作期间影响您的工作负载。但对于较大的代理,由于容量增量较大,您可能需要添加比所需更多的备用容量。
但是,集群中的代理越多,完成维护和更新操作所需的时间就越长。该服务一次将这些更改依次应用于一个代理,以最大限度地减少对集群可用性的影响。根据最佳实践配置集群时,您已经添加了足够的备用容量,不会在这些操作期间影响您的工作负载。但完成操作所需的时间仍然是需要考虑的因素,因为您需要等待一个操作完成,然后才能运行另一个操作。
您需要找到适合您的工作量的平衡点。 小型代理更灵活,因为它们为您提供更小的容量增量。 但是,拥有太多小型代理会增加完成维护操作所需的时间,并增加失败的可能性。 具有较少大型代理的集群可以更快地完成更新操作。 但是在代理失败的情况下,它们具有更大的容量增量和更高的爆炸半径。
向上扩展以处理 CPU 密集型工作负载
到目前为止,我们一直关注代理的网络吞吐量。 但是还有其他因素决定集群的吞吐量和延迟。 其中之一是加密。 Apache Kafka 有多个层,其中加密可以保护传输中和静态数据:存储在存储卷上的数据加密、代理之间的流量加密以及客户端和代理之间的流量加密。
Amazon MSK 始终加密您的静态数据。 您可以指定希望 Amazon MSK 用于加密静态数据的 AWS Key Management Service (AWS KMS) 客户主密钥 (CMK)。 如果您不指定 CMK,Amazon MSK 会为您创建一个 AWS 托管 CMK 并代表您使用它。 对于传输中的数据,您可以选择在生产者和代理之间(传输中加密)、代理之间(集群内加密)或两者启用数据加密。
打开集群内加密会强制代理加密和解密单个消息。 因此,通过网络发送消息不能再利用有效的零拷贝操作。 这会导致额外的 CPU 和内存带宽开销。
下图显示了这些选项对具有 m5.large 和 m5.2xlarge 代理的三节点集群的性能影响。
对于 p99 放置延迟,启用集群内加密会对性能产生重大影响。 如上图所示,扩大代理规模可以减轻这种影响。 p99 将具有传输中和集群内加密的 m5.large 集群的延迟设置为 52 MB/秒,吞吐量超过 200 毫秒(左图中的红色和绿色虚线)。 将集群扩展到 m5.2xlarge 代理将相同吞吐量下的 p99 放置延迟降低到 15 毫秒以下(右图中的红色和绿色虚线)。
还有其他因素会增加 CPU 要求。 压缩和日志压缩也会影响集群的负载。
为不从流的尖端读取的消费者扩大规模
我们设计了性能测试,以便消费者始终从主题的提示开始阅读。 这实际上意味着代理可以直接从内存中为来自消费者的读取提供服务,而不会导致对 Amazon EBS 的任何读取 I/O。 与帖子的所有其他部分相比,我们放弃了这个假设,以了解落后的消费者如何影响集群性能。 下图说明了这种设计。
当消费者落后或需要从失败中恢复时,它会重新处理旧消息。 在这种情况下,保存数据的页面可能不再驻留在页面缓存中,代理需要从 EBS 卷中获取数据。 这会导致卷和非顺序 I/O 读取的额外网络流量。 这会显着影响 EBS 卷的吞吐量。
在极端情况下,回填操作可以重新处理完整的事件历史记录。 在这种情况下,该操作不仅会对 EBS 卷造成额外的 I/O,还会将大量保存历史数据的页面加载到页面缓存中,从而有效地驱逐保存更新数据的页面。 因此,稍微落后于主题提示并且通常直接从页面缓存读取的消费者现在可能会导致 EBS 卷的额外 I/O,因为回填操作已逐出他们需要从内存中读取的页面。
缓解这些情况的一种选择是启用压缩。 通过压缩原始数据,代理可以在页面缓存中保留更多数据,然后再将其从内存中逐出。 但是,请记住压缩需要更多的 CPU 资源。 如果您无法启用压缩,或者如果启用压缩无法缓解这种情况,您还可以通过向上扩展增加代理可用的内存来增加页面缓存的大小。
使用突发性能来适应流量高峰
到目前为止,我们一直在研究集群的持续吞吐量限制。这是集群可以无限期维持的吞吐量。对于流式工作负载,重要的是要相应地了解吞吐量要求和大小的基线。但是,Amazon EC2 网络、Amazon EBS 网络、Amazon EBS 存储系统是基于信用体系的;它们提供一定的基线吞吐量,并且可以根据实例大小在一定时期内突增至更高的吞吐量。这直接转化为 MSK 集群的吞吐量。 MSK 集群具有持续的吞吐量限制,并且可以在短时间内突增至更高的吞吐量。
下图中的蓝线显示了具有两个消费者组的三节点 m5.large 集群的总吞吐量。在整个实验过程中,生产者都试图尽快将数据发送到集群中。因此,尽管集群持续吞吐量限制的 80% 约为 58 MB/秒,但集群可以在近半小时内突增至远高于 200 MB/秒的吞吐量。
可以这样想:在配置集群的底层基础设施时,您基本上是在为集群提供一定的持续吞吐量限制。鉴于突发能力,集群可以在一段时间内瞬间吸收更高的吞吐量。例如,如果您的工作负载的平均吞吐量通常约为 50 MB/秒,则上图中的三节点 m5.large 集群可以在大约半小时内进入其正常吞吐量的四倍以上。而且不需要任何更改。这种突发的更高吞吐量是完全透明的,不需要任何扩展操作。
这是吸收突然的吞吐量峰值而无需扩展集群的非常强大的方法,这需要时间才能完成。此外,额外的容量还有助于响应操作事件。例如,当代理正在进行维护或需要在集群内重新平衡分区时,他们可以使用突发性能使代理更快地在线和恢复同步。突发容量对于从影响整个可用区并导致大量复制流量响应事件的操作事件中快速恢复也非常有价值。
监控和持续优化
到目前为止,我们关注的是集群的初始大小。但是在您确定了正确的初始集群大小之后,调整规模的工作不应停止。重要的是在生产运行后继续检查您的工作负载,以了解代理大小是否仍然合适。您最初的假设可能不再适用于实践,或者您的设计目标可能已经改变。毕竟,云计算的一大好处是您可以通过 API 调用来调整底层基础设施。
正如我们之前提到的,您的生产集群的吞吐量应该以其持续吞吐量限制的 80% 为目标。当底层基础设施因为超出吞吐量限制时间过长而开始出现节流时,您需要对集群进行扩容。理想情况下,您甚至可以在达到这一点之前扩展集群。默认情况下,Amazon MSK 公开三个指标,指示何时将此限制应用于底层基础设施:
- BurstBalance – 指示 EBS 卷的 I/O 突增积分的剩余余额。 如果此指标开始下降,请考虑增加 EBS 卷的大小以提高卷基线性能。 如果 Amazon CloudWatch 没有为您的集群报告此指标,则您的卷大于 5.3 TB,不再受突增积分的影响。
- CPUCreditBalance – 仅与 T3 系列的代理相关,指示可用 CPU 积分的数量。 当此指标开始下降时,代理正在消耗 CPU 积分以突破其 CPU 基准性能。 考虑将代理类型更改为 M5 系列。
- TrafficShaping – 一种高级指标,指示由于超出网络分配而丢弃的数据包数量。 当为集群配置 PER_BROKER 监控级别时,可以获得更详细的信息。 如果此指标在您的典型工作负载期间升高,请扩大代理。
在前面的示例中,我们看到在网络信用耗尽并应用流量整形后集群吞吐量大幅下降。 即使我们不知道集群的最大持续吞吐量限制,下图中的 TrafficShaping 指标也清楚地表明我们需要扩展代理以避免 Amazon EC2 网络层上的进一步限制。
Amazon MSK 公开了额外的指标,可帮助您了解您的集群是过度配置还是配置不足。 作为规模调整练习的一部分,您已经确定了集群的持续吞吐量限制。 您可以监控甚至针对集群的 BytesInPerSec、ReplicationBytesInPerSec、BytesOutPerSec 和 ReplicationBytesInPerSec 指标创建警报,以便在当前集群大小不再适合当前工作负载特征时收到通知。 同样,您可以监控 CPUIdle 指标,并在您的集群在 CPU 利用率方面供应不足或供应过多时发出警报。
这些只是从基础设施角度监控集群规模的最相关指标。 您还应该监控集群和整个工作负载的健康状况。
一个测试 Apache Kafka 性能的框架
如前所述,您必须运行自己的测试来验证集群的性能是否符合您的特定工作负载特征。我们在 GitHub 上发布了一个性能测试框架,可帮助自动化许多测试的调度和可视化。我们一直在使用相同的框架来生成我们在本文中讨论过的图表。
该框架基于作为 Apache Kafka 发行版一部分的 kafka-producer-perf-test.sh 和 kafka-consumer-perf-test.sh 工具。它围绕这些工具构建自动化和可视化。
对于受制于 bust 功能的较小代理,您还可以将框架配置为首先在一段较长的时间内产生超额负载,以耗尽网络、存储或存储网络信用。信用耗尽完成后,框架运行实际性能测试。这对于衡量可以无限期维持的集群性能很重要,而不是衡量只能维持一段时间的峰值性能。
要运行您自己的测试,请参阅 GitHub 存储库,您可以在其中找到 AWS 云开发工具包 (AWS CDK) 模板和有关如何配置、运行和可视化性能测试结果的其他文档。
结论
我们从基础架构的角度讨论了影响 Apache Kafka 性能的各种因素。虽然我们专注于 Apache Kafka,但我们也了解了 Amazon EC2 网络和 Amazon EBS 性能特征。
要为您的集群找到合适的大小,请从您的用例逆向确定吞吐量、可用性、持久性和延迟要求。
根据您的吞吐量、存储和持久性要求,从集群的初始大小开始。横向扩展或使用预配置的吞吐量来增加集群的写入吞吐量。向上扩展以增加可以从集群中消费的消费者数量。扩大规模以促进传输中或集群内加密以及未阅读信息流尖端的消费者。
通过运行性能测试来验证此初始集群大小,然后微调集群大小和配置以满足其他要求,例如延迟。为生产集群添加额外的容量,以便它们能够承受代理的维护或丢失。根据您的工作负载,您甚至可以考虑承受影响整个可用区的事件。最后,继续监控您的集群指标并调整集群大小,以防您的初始假设不再成立。