没有动物园的Kafka.

2021-04-01 19:35:52

在ApacheKafka®的核心侧坐在日志 - 一个简单的数据结构,它使用顺序操作与底层硬件合作。高效的磁盘缓冲和CPU高速缓存使用,预取,零复制数据传输以及许多其他益处从以日志为中心的设计出现,导致它所以的高效率和吞吐量。对于那些新的Kafka,主题 - 以及其作为提交日志的底层实施 - 通常是他们了解的第一件事。

但是日志本身的代码构成了整个系统的相对小部分。 kafka的codebase比例远远负责在群集中的许多经纪商中排列分区(即,日志),分配领导,处理失败等。这是使Kafka成为可靠和可信的分布式系统的代码。

从历史上看,Apache Zookeeper是这种分布式代码如何工作的关键部分。 Zookeeper提供了持有该系统最重要的事实的Metadata的权威商店:在划分的地方,哪个副本是领导者等等。使用ZooKeeper的使用早期就是一种强大而经过验证的工具。但最终,Zookeeper是一个一致的日志顶部有点特殊文件系统/触发API。 Kafka是一个一致的日志顶部的PUB / sub API。这导致了操作系统调整,配置,监视,安全性以及两个日志实现,两个网络层和两个安全实现的通信和性能的原因,每个都具有不同的工具和监视钩子。它变得不必要地复杂。这种固有和不可避免的复杂性促使最近的举措取代了ZooKeeper,其中内部法定人服务完全在Kafka本身内运行。

当然,取代Zookeeper是一款相当大的工作岗位,去年4月我们开始了一个社区倡议,以加速日程安排并在年底之前提供工作系统。

我刚坐在杰森,科林和kip-500团队中,经历了完整的Kafka Server生命周期,生产,消费和所有自动统一。漂亮的甜蜜!

因此,我们非常高兴地说,KIP-500代码的早期访问已致力于中继,预计将包含在即将到来的2.8释放中。首次,您可以在没有Zookeeper的情况下运行Kafka。我们称之为Kafka Raft元数据模式,通常缩短到克拉特(发音等工艺)模式。

请注意,此早期访问版本中有一些功能不可用。我们还不支持使用ACL和其他安全功能或交易。此外,分区重新分配和JBOD在克拉特模式下不受支持(这些预计将在Apache Kafka在年后发布中提供)。因此,考虑到仲裁控制器实验软件 - 我们不建议将其进行生产工作负载。但是,如果您尝试了该软件,您将找到一系列新的优点:部署和操作更简单,您可以整体运行Kafka作为单一进程,它可以适应每个群集的更多分区(参见测量以下)。

如果您选择使用新的仲裁控制器运行Kafka,则Kafka Controller和Zookeeper先前所承诺的所有元数据职责都将合并为此新服务,在Kafka集群本身内运行。仲裁控制器也可以在专用硬件上运行,如果您有一个要求它的用例。

但内部,它变得有趣。仲裁控制器使用新的KRAFT协议来确保在仲裁中准确地复制元数据。此协议以许多方式与Zookeeper的Zab协议相似,并且对RAFT,但具有一些重要的差异,一个值得注意的差异,并且一个值得支持的差异是它使用事件驱动的架构。

仲裁控制器使用事件源存储模型存储其状态,这确保了内部状态机可以始终准确地重新创建。用于存储此状态的事件日志(也称为元数据主题)通过快照定期删除,以保证日志不能无限期地生长。仲裁中的其他控制器通过响应其在其日志中创建和存储的事件来遵循活动的控制器。因此,例如,如果由于分区事件引起的一个节点暂停,例如,它可以快速追赶它在重新加入时访问日志的任何事件。这显着降低了不可用窗口,从而提高了系统的最坏情况恢复时间。

克拉夫协议的事件驱动性质意味着,与基于ZooKeEper的控制器不同,仲裁控制器不需要在变为活动之前从zookeeper加载状态。当领导层发生变化时,新的活动控制器已包含内存中的所有已提交的元数据记录。更重要的是,克拉夫协议中使用的相同事件驱动机制用于跟踪群集中的元数据。以前用RPC处理的任务现在是福利事件驱动以及使用实际日志进行通信。这些变化的令人愉快的结果 - 以及非常烘焙到原始设计的变化 - 是Kafka现在可以支持比以前的更多分区。让我们更详细地讨论这一点。

Kafka群集可以支持的分区数由两个属性确定:每个节点分区计数限制和群集范围的分区限制。两者都很有趣,但到目前为止,元数据管理是集群范围限制的主要瓶颈。以前的Kafka改进提案(KIPS)已经改进了每个节点限制,尽管总是可以完成更多。但Kafka的可扩展性主要取决于添加节点以获得更多容量。这是群集范围限制变得重要的位置,因为它定义了系统内的可扩展性的上限。

新的仲裁控制器旨在处理每群集数量大的分区。为了评估这一点,我们在2018年之前运行了类似于先前运行的测试,以宣传Kafka的固有分区限制。这些测试测量关闭和恢复所花费的时间,这是旧控制器的O(#Partitions)操作。这是此操作,将kafka在今天在单个集群中支持的分区数上的上限置于上限。

作为上述帖子中的jun Rao在上面引用的帖子中解释的以前的实施,可以实现200k分区,限制因素是在外部共识(Zookeeper)和内部领导者管理(Kafka Controller)之间移动关键元数据所花费的时间。使用新的仲裁控制器,这两个角色都由相同的组件提供。事件驱动方法意味着控制器故障转移现在近乎瞬时。以下是在我们的实验室中执行的群集运行200万分区(10x上一个上限)的摘要编号:

对受控和不受控制的关机的措施都很重要。受控关闭影响常用操作场景,例如滚动重启:部署软件更改的标准过程,同时保持始终保持可用性。从不受控制的停机中恢复可以说是更重要的是,它设置系统的恢复时间目标(RTO),例如在意外的失败之后,例如VM或POD崩溃或数据中心变得不可用。虽然这些措施只是更广泛的系统性能的指标,但他们直接测量Zookeeper使用施加的众所周知的瓶颈。

请注意,受控和不受控制的测量不直接可比较。不受控制的关机案件包括新领导人所采取的时间,而受控案例没有。这种差异是刻意保持受控案例与Jun Rao的原始测量一致。

Kafka经常被视为重量级基础设施以及管理Zookeeper-A第二个单独分布式系统的复杂性 - 是为什么这种感知存在的重要组成部分。这通常会导致项目以选择更轻量的消息队列,当他们开始时出示一个传统的队列,如ActiveMQ或Rabbitmq - 并在其比例要求时转向Kafka。

这是不幸的,因为Kafka提供的抽象在提交日志中形成,同样适用于您可能在启动时看到的小规模工作负载,因为它是Netflix或Instagram的高吞吐量。更重要的是,如果要添加流处理,则需要Kafka及其提交日志抽象,无论是使用Kafka Streams,KSQLDB还是其他流处理框架。但由于管理两个单独的系统的复杂性 - Kafka和Zookeeper-user常认为他们必须在比例之间选择或易于入门。

这已不再是这种情况。 KIP-500和KRAFT模式提供了一种伟大的轻量级方式来开始Kafka,或者将其用作替代品如Actimemq或Rabbitmq等单片经纪人。轻量级,单流程部署也更适合边缘方案和使用轻质硬件的人。云增加了同样的问题的有趣,切向角度。汇率云等托管服务完全消除了运营负担。因此,您是否正在寻求运行自己的群集,或者为您运行,您可以从中开始且增长(潜在地)大规模比例,因为您的基础用例展开 - 所有具有相同的基础架构。让我们看看单程部署的样子。

新的仲裁控制器今天在实验模式下在后备箱中提供,预计将包含在即将到来的Apache Kafka 2.8版本中。那么你能做什么呢?如上所述,一个简单但非常酷的新功能是能够在下面的简短演示中创建一个过程Kafka群集。

当然,如果要扩展到支持更高的吞吐量并添加容错的复制,只需添加新的代理流程。如您所知,这是基于Kraft的仲裁控制器的早期访问释放。请不要为关键工作负载使用它。在接下来的几个月里,我们将添加最终缺失的碎片,执行协议的TLA +建模,并在Confluent Cloud中强化仲裁控制器。

您可以立即尝试新的仲裁控制器。在github上看到完整的自述文件。

如果没有Apache Kafka社区,并且一组分布式系统工程师在大流行期间,这是一个巨大的努力,这一直是(并继续是)巨大的努力。我们想简要介绍一个特别感谢Colin Mccabe,Jason Gustafson,Ron Dagostino,Boyang Chen,David Arthur,Jose Garcia Sancio,Guozang Wancio,Guokhang Wang,Alokhiol,邓自明,Sagar Rao,Feyman,Chia-Ping Tsai,Jun Rao ,Heidi Howard,以及帮助实现这一目标的Apache Kafka社区的所有成员。

本斯托斯福德是CTO办公室的领导技术专家。他是一个数据技术专家,他们在汇合,思考和企业组织的一系列系统上工作。他对Apache Kafka的贡献包括Kafka的复制协议和其他相关项目的工作。他也是O'Reilly Book:设计事件驱动系统的作者。

Ismael Juma是融合在Apache Kafka和Confluent Cloud的汇合的工程领导者。 Ismael在汇合云中的无限存储等举措上工作,用Kafka Raft(牛皮纸)元数据法定值替换Zookeeper。 Ismael还是Apache Kafka提名和项目管理委员会(PMC)成员。