手记

AutoMQ:无需 Cruise Control 实现 Kafka 的自动分区再平衡

导读:AutoMQ是一款贯彻云优先理念来设计的 Kafka 替代产品。AutoMQ 创新地对 Apache Kafka 的存储层进行了基于云的重新设计,在 100% 兼容 Kafka 的基础上通过将持久性分离至 EBS 和 S3 带来了 10x 的成本降低以及 100x 的弹性能力提升,并且相比 Apache Kafka 拥有更佳的性能。

在本文中,Vu Trinh 探讨了 AutoMQ 如何通过消除代理之间的数据移动来彻底改变 Kafka 分区重新分配流程。文章首先分析了标准的 Kafka 分区和重新分配过程,以及当前方案(如 Cruise Control)的局限性。接着深入讲解了 AutoMQ 如何利用云原生架构,实现与 Kafka 100% 兼容,并将数据存储在对象存储上,从而简化操作并提高效率。最后,本文详细介绍了 AutoMQ 的 AutoBalancer,它能够精确且轻松地自动实现负载均衡。了解 AutoMQ 如何有效解决 Kafka 的重新平衡挑战。阅读原文:AutoMQ: Achieving Auto Partition Reassignment In Kafka Without Cruise Control

简介

如果你在公司内部管理过 Kafka 部署,可能会执行跨集群分区重新分配操作。由于 Kafka 中计算和存储的紧密耦合,当集群成员发生变化(如添加或移除 broker)或用户希望在 broker 之间平衡负载时,分区副本需要重新分配到不同的 broker,从而导致数据迁移。

虽然 Kafka 提供了处理重新分配过程的脚本,但它需要用户干预,并且在规划方面缺乏稳健性。诸如 Cruise Control 之类的工具,基于集群状态提供自动化的副本平衡,并提供更详细的重新分配规划。

然而,数据迁移的问题仍然存在。

本周,我们将探讨 AutoMQ 如何解决 Kafka 的再平衡挑战。AutoMQ 是一款云原生解决方案,提供 100% Kafka 兼容性,同时将数据完全存储在对象存储中。这种方法提供了一种高性价比的 Kafka 替代方案,同时不牺牲低延迟和高吞吐量性能。更重要的是,您不再需要在 Broker 之间传输数据。


Kakfa Partitions

首先让我们回顾Kafka相关术语。

在 Kafka 中,数据单元是消息。消息在 Kafka 中被组织成主题。可以将消息视为数据库系统中的行,而主题则相当于表。一个主题被分成多个分区。

图像由作者创建。

主题的每个分区对应一个逻辑日志。在物理层面,日志实现为一组大小大致相同的段文件(例如,1GB)。每当消息写入分区时,Broker 会将该消息追加到最后一个段文件。

图像由作者创建。

为了确保数据的持久性和可用性,分区将被复制到可配置数量的Broker (代理)。

图像由作者创建。

当一个 Broker(代理)出现故障时,这一机制可以自动执行副本的故障切换,确保消息尽管发生故障仍然可用。每个 Kafka 分区通常有一个 leader(领导者)和零个或多个 followers(跟随者,存储副本的节点)。所有写操作必须发送到分区的 leader,而读操作可以由 leader 或分区的 followers 处理。

Kafka 以轮询的方式将分区副本分布在整个集群中,以避免将高流量主题的所有分区集中在少数节点上。


Kafka 中的副本重新分配

考虑到副本分布在整个集群中,当现有 broker 崩溃或新 broker 添加时会发生什么?Kafka 副本需要重新分配。假设我们有三个 broker 和两个分区,每个分区有两个副本:

图像由作者创建。

  • 若某个Broker(代理)失败,Kafka会自动将该Broker管理的分区的领导权重新分配给持有这些分区副本的其他Brokers。为了维持复制因子,Kafka可能最终会在其他可用的Brokers上创建这些分区的新副本。

图像由作者创建。

  • 一旦新增Broker,副本会被重新分配,以确保各Broker之间的负载平衡。

图像由作者创建。

除了集群成员的变更外,平衡 Broker 之间的工作负载还需要重新分配分区副本。均匀地在 Broker 之间分布数据有助于防止热点问题,因为某些分区可能会接收到比其他分区更多的流量。此外,确保数据在 Broker 之间均匀分布能够优化资源利用率。

开源版本的 Kafka 提供了一个工具来促进分区重新分配,称为 kafka-reassign-partitions (bin/kafka-reassign-partitions.sh)。这个工具可以在三种模式下操作:

  • generate:此模式用于创建分区重新分配计划。给定一个主题和 Broker 的列表,该工具生成一个候选重新分配计划,将主题分区移动到新的 Broker。

  • execute:在此模式下,工具根据用户提供的重新分配计划执行分区重新分配。此计划可以是自定义的、手动创建的,也可以通过使用 --generate 选项生成的。

  • verify:该工具验证最近一次 --execute 执行期间列出的所有分区的重新分配状态。

然而,用户手动完成再分配过程容易出错且效率低下。那么,有没有办法实现再分配的自动化?幸运的是,已经有第三方工具专门为此目的开发。


LinkedIn 的 Cruise Control

Cruise Control 是一个帮助大规模运行 Apache Kafka 集群的工具。由于其受欢迎程度,许多公司拥有越来越多的 Kafka 集群。在 LinkedIn 管理约 7000 多个 Kafka brokers 意味着平衡 Kafka 工作负载是一个巨大的挑战。此外,在大型 Kafka 集群中监控和检测问题也是至关重要的。

Cruise Control 提供以下能力:

  • 资源利用率跟踪

  • 当前 Kafka 集群状态的可观察性

  • Kafka 集群的异常检测、告警和自愈功能

  • 管理操作,例如添加/删除 Brokers 或重新平衡集群

  • 多重目标重新分配计划的生成

Cruise Control 依赖最新的副本负载信息来优化集群。它定期收集 Broker 和分区级别的资源利用情况,以捕捉每个分区的流量模式。利用这些模式,确定每个分区对 Broker 的负载影响。然后,该工具构建一个工作负载模型来模拟 Kafka 集群的性能。目标优化器根据用户定义的一组目标,探索生成集群工作负载优化计划的各种方法。

图像由作者创建。

这种方法与kafka-reassign-partitions不同,虽然Kafka的原生工具仅根据提供的输入重新分配分区,但Cruise Control使用工作负载建模来提供更全面的重新平衡计划目标。

虽然Cruise Control有助于降低重新平衡操作的成本,但网络上传输数据的需求仍然存在。当数据在broker之间传输时,集群必须等待一段时间才能达到平衡状态。这导致无论是使用Cruise Control还是其他第三方工具,重新平衡在执行过程中都可能存在不精确性。这些工具只能基于集群的当前快照做出决策。鉴于Kafka的数据复制要求,决策过程较为缓慢。因此,依赖于这些决策的集群快照可能会发生显著变化,导致准确性降低。

这个问题在Kafka中依然存在,因为它设计上需要保持存储和计算的紧密集成。


AutoMQ:无需再进行数据移动。

当我们讨论AutoMQ时,情况变得很简单。

AutoMQ利用Apache Kafka代码实现了对Kafka协议的100%兼容,同时引入共享存储架构以取代Kafka代理的本地磁盘。其目标是使系统完全无状态化。

虽然Kafka代理将消息直接写入操作系统的页面缓存,但AutoMQ代理则首先将消息写入堆外内存缓存,并在批量处理数据后再写入对象存储。为确保在代理从内存向对象存储传输数据过程中遭遇故障时的数据耐久性,AutoMQ引入了可插拔的预写日志(Write-Ahead Log,WAL)到磁盘。代理必须在将消息写入S3之前,先验证消息已存储在WAL中。一旦收到消息,代理便将其写入内存缓存,并只有在消息被持久化到WAL后才进行确认。在代理故障时,AutoMQ使用WAL中的数据进行恢复。

图像由作者创建。

通过这种方式,AutoMQ实现了计算与存储的完全分离。AutoMQ的设计暗示了两个基本事实:

图像由作者创建。

  • 由于对象存储服务确保数据的持久性和可用性,因此无需在代理之间复制数据。因此,每个分区只有一个副本,即领导者。

  • 代理是完全无状态的;代理与分区之间的关系仅通过元数据进行管理,而不是将相关的分区数据物理存储在本地代理磁盘上。

因此,重新平衡过程变得极其简单。数据不需要移动;AutoMQ只需调整代理与分区之间的元数据映射即可。这使得决策得以迅速、准确、高效地执行。

关于元数据,AutoMQ使用Kafka的KRaft模式(Kafka Raft)进行元数据管理。最初,Kafka依赖于单独的ZooKeeper服务器来管理集群元数据。通过KRaft模式,Kafka使用基于Raft的内部控制器法定人数——一组负责维护和确保元数据一致性的代理。在KRaft模式下,每个代理保留元数据的本地副本。同时,控制器法定人数的领导者管理更新并将其复制到所有代理,从而减少运营的复杂性和潜在的故障点。

AutoMQ 将集群元数据(如分区和代理之间的映射)存储在控制器仲裁的领导者中。只有领导者可以修改这些元数据;如果代理想要更改它,必须与领导者通信。元数据会被复制到每个代理;控制器会将元数据的任何更改广播给每个代理。


AutoBalancer:AutoMQ 的自平衡功能

目标

目标指一组指导 Kafka 集群优化和平衡的目标或约束。这些目标定义了具体的要求,如在代理之间的负载分布、资源利用限制、分区复制以及延迟目标。

与 Cruise Control 提供预定义的目标并允许用户自行编写不同,AutoMQ 的自平衡特性 AutoBalancer 通过提供一套完善、经过充分测试的目标,简化了操作。

  • 每个 AutoMQ 的目标都定义了一个阈值和一个可接受的范围。例如,若某个目标涉及以 50% 的 CPU 利用率为阈值,并设定 ±20% 的范围,则可接受范围为 30% 到 70%。只要流量保持在此范围内,目标便被视为已达成。

图像由作者创建。

  • 检测类目标包括检查资源容量(如 CPU 或网络 I/O)的违规情况。

图像由作者创建。

为了确保在执行优化目标后保持稳定性,AutoMQ会为检测和优化目标选择合适的阈值和范围。例如,缩小优化目标的范围可以确保处理后的结果更加精确。

某个特定目标可能比其他目标具有更高的优先级。AutoMQ根据优先级将目标分类为硬性目标和软性目标:

  • 硬性目标:这些目标必须在任何情况下都要实现,例如限制分区数量或设置最大代理流量限制。

  • 软性目标:如果与硬性目标冲突,这些目标可以忽略。例如,流量平衡目标。

在目标管理方面,AutoMQ使用数学模型表示每个目标。每个模型根据特定数学条件指示代理是否满足目标。在某些情况下,实现目标的操作可能有多种选择(例如,将分区从代理A移动到代理B或从代理A移动到代理C,两者都能帮助平衡集群流量)。AutoMQ还使用一个数学系统来决定在给定情况下的最佳决策。每个决策根据相关的目标参数进行评分,得分最高的决策将被执行。

组件

AutoBalancer 的实现主要包括以下三个组件:

图像由作者创建。

  • Metrics Collector(指标收集器):Apache Kafka 提供了一个基于 YammerMetrics(Java 的一个指标库)和 KafkaMetrics 的指标收集系统。这些指标可以通过 MetricsRegistry 和 MetricsReporter 接口进行监控。基于这些接口,AutoMQ 实现了一个 reporter(报告器),用来定期收集预定义的指标,如网络流量吞吐量。AutoMQ 使用一个内部主题在 broker(代理)和 controller(控制器)之间传输指标;报告器在收集到指标后,会将其编译成多个消息并发送到内部主题。

  • State Manager(状态管理器):在 controller 上,AutoMQ 维护一个 ClusterModel(集群模型)来表示集群的当前状态和分区负载。集群的变化,如 broker 的增加、移除,或分区的重新分配和删除,都是通过监控 KRaft(Kafka 的 Raft 实现,用于元数据)元数据来更新 ClusterModel。同时,controller 持续从内部主题中消费,预处理提取的指标,并更新 ClusterModel,以确保它准确地反映集群的当前状态。

  • 决策调度器:该组件旨在帮助集群实现特定目标,例如限制每个 broker(Kafka 中的消息代理者)的分区数或限制流量至单一 broker。在 AutoMQ 中,只有活跃的控制器参与决策和调度。在开始决策过程之前,AutoMQ 会捕捉 ClusterModel 的快照(反映 Kafka 集群状态的内部模型),并利用该快照的状态进行后续调度。在快照完成后,ClusterModel 仍可以继续更新。AutoMQ 的决策过程采用类似于 Cruise Control(一个用于 Kafka 集群管理的开源工具)的启发式调度算法。

典型过程

图像由作者创建。

接下来,我们深入探讨一下 AutoMQ 自平衡的典型过程:

  • 自平衡调度器在每个间隔时间(例如每 60 秒)启动,检查集群是否满足所有设定的目标。如果满足,调度器将进入休眠状态。

  • 如果没有,调度器将会获取违反目标的代理者(broker)列表。

  • 对于每个违反目标的代理者,调度器将制定分区重新分配计划,以尝试使该代理者符合目标。

  • 随后,调度器将验证分区重新分配方案是否可行。如果可行,该计划将在集群内执行。如果不可行,则该代理者无法达到目标,调度器将继续检查列表中的其他代理者。

情景

让我们回顾一下AutoBalancer在不同情景下的行为:

在云计算的背景下,“机架”可以指一个可用区。

  • 主题创建:AutoBalancer在主题创建时支持机架感知。它可以将数据随机分布在不同的机架上,同时考虑每个机架的“权重”。权重较高的机架将平均接收比权重较低的机架更多的数据。在同一机架内,数据的分配基于每个代理(broker)的权重。如果某个代理的权重较高,它将在该机架内接收更多的数据。

  • 添加代理:AutoBalancer支持逐步热启动新添加的代理。系统不会将所有流量一次性发送到新代理,而是随时间逐步增加流量,以防止过载。在扩展过程中,AutoBalancer还尽量减少跨机架的流量,以避免网络拥塞,除非涉及到新机架。

  • 删除代理:AutoBalancer支持自动将被删除代理所处理的分区迁移到其他代理。它努力将分区迁移到与被删除代理同一机架的代理上。

  • 吞吐量不均:系统根据每个代理(broker)处理特定请求速率的能力分配流量。每个物理代理都被赋予了一个“权重”,这个权重衡量了其负载处理能力;例如,一个性能更高的代理可能被分配更高的权重。AutoMQ通过评估诸如网络、IO(输入/输出)、和CPU(中央处理器)核心等因素来确定每个代理的权重。系统会持续监控每个节点的负载和处理能力,以调整调度,防止任何单个代理过载。

  • 单节点故障:AutoBalancer支持识别性能较慢的代理,这可能表明潜在问题。系统能通过将任务转移到健康节点来减少这些性能较慢代理的负载,使得较慢的代理能在不影响系统性能的情况下恢复。

AutoBalancer与Cruise Control的比较

在结束本文之前,让我们来回顾一下AutoBalancer和Cruise Control之间的一些差异:

  • AutoMQ原生支持AutoBalancer功能,省去了复杂的操作和部署。相反,Cruise Control需要单独部署和管理,同时与Kafka集群一起运行。

  • Apache Kafka在平衡流量时需要复制大量数据以移动分区,导致执行成本高昂。因此,Cruise Control的平衡目标设定严格,仅在流量波动较小时才显示出明显效果。在流量负载变化显著的情况下,Cruise Control的效果有限。AutoMQ通过将计算与存储分离的设计,更适合处理复杂负载场景。

  • 得益于其设计,AutoMQ使AutoBalancer能够比Cruise Control更快地执行副本重新分布。此外,由于AutoBalancer是AutoMQ的有机组成部分,它可以直接消费KRaft(Kafka Raft)日志,从而更迅速地响应集群变化。


尾声

感谢您阅读到这里。

在本文中,我们回顾了一些Kafka术语,例如分区副本如何在代理(brokers)之间分布,以及当集群成员变更时为什么需要进行副本重新分布。然后,我们探讨了Kafka在重分布过程中的原生解决方案。

接下来,我们考察了诸如 Cruise Control 等第三方工具如何帮助用户以更方便和强大的方式简化流程。我们发现,AutoMQ 能完全解决重新分配过程中的数据传输问题,因为数据存储在 broker 之外,仅需调整元数据。最后,我们深入探讨了 AutoMQ 的自平衡功能 AutoBalancer。

虽然我们看到 Cruise Control 在 Kafka 重新分配过程中能帮助用户,但核心问题依旧存在:数据仍需通过网络在 broker 之间传输。而通过创新的架构,AutoMQ 完全将数据存储在对象存储中,使许多 Kafka 操作对用户而言更加简化,尤其是在分区重新分配过程中。当分区被分配到不同 broker 时,仅需调整元数据,从而实现更高效、更加稳健的内部自平衡。


参考文献:

[1] 感谢 AutoMQ 的解决方案架构师与首席布道师 Kaiming Wan 的协助。

[3] AutoMQ 博客: https://www.automq.com/blog

[5] Kafka Cruise Control GitHub 仓库: https://github.com/linkedin/cruise-control


0人推荐
随时随地看视频
慕课网APP