什么时候用RabbitMQ 什么时候用Apache Kafka?

什么时候用RabbitMQ 什么时候用Apache Kafka?

如果您要问自己Apache Kafka是否比RabbitMQ更好,或者RabbitMQ是否比Apache Kafka更可靠,那么我想在这里停下来。 本文将从更广泛的角度讨论这两个方面。 它着重于两个系统提供的功能,并将指导您就何时使用哪个系统做出正确的决定。

网络上的某些文章使Apache Kafka在RabbitMQ面前大放异彩,而其他文章则相反。 我觉得知道是否要使用RabbitMQ或Kafka的决定取决于您的项目需求是很重要的,只有在合适的情况下将它们与正确的设置一起使用时,才能进行真正的比较。

84codes和我从事该行业已有很长时间了,他们通过CloudAMQP服务为RabbitMQ提供了托管解决方案,并通过CloudKarafka服务为Apache Kafka提供了托管解决方案。 由于我已经看到CloudAMQP和CloudKarafka用户如此多的用例和不同的应用程序设置,因此我觉得我可以根据自己的经验在RabbitMQ和Apache Kafka上权威地回答用例问题。

在本文中,我的任务是基于我多年来的许多开发人员到开发人员的聊天中分享见解,并试图传达他们对为什么选择其他特定消息代理服务的想法。

本文使用的术语包括:

  • 消息队列是RabbitMQ中的队列(queue),Kafka中的“队列(queue)”被称为日志(log),但是为了简化本文中的信息,我将引用队列,而不是一直切换到“日志”。
  • kafka中的一条消息通常被称为一条记录(record),但是同样,我将引用消息以简化此处的信息。
  • 当我在Kafka中撰写主题(topic)时,您可以将其视为消息队列中的一种分类。 Kafka主题分为多个分区,每个分区包含不可更改顺序的记录。

两种系统通过队列(queue)或主题(topic)在生产者和消费者之间传递消息。 一条消息可以包含任何种类的信息。 例如,它可以具有有关网站上发生的事件的信息,也可以是触发另一个应用程序上的事件的简单文本消息。

这种系统是连接不同组件,构建微服务,实时数据流(real-time streaming)或将工作传递给远程工作者时的理想选择。

据Confluent称,世界500强公司中有超过三分之一的公司使用Apache Kafka。 Zalando,WeWork,Wunderlist和Bloomberg等各种大型行业也都依赖RabbitMQ。

什么时候用RabbitMQ 什么时候用Apache Kafka?

大问题; 何时使用Kafka,何时使用RabbitMQ?

不久前,我在*上写了一个答案,以回答“是否有理由使用RabbitMQ替换Kafka?”。 答案只有几行,但事实证明,这是许多人发现有用的答案。

我将尝试将答案分解为子答案,并尝试解释每个部分。 首先,我写道-“ RabbitMQ是可靠,成熟的通用消息代理,它支持多种协议,例如AMQP,MQTT,STOMP等。 RabbitMQ可以处理高吞吐量。 它的一个常见用例是处理后台作业或充当微服务之间的消息代理。 Kafka是一种消息总线,针对高输入量数据流和重放进行了优化。 Kafka可以看作是持久的消息代理,应用程序可以在其中处理和重新处理磁盘上的流数据。”

关于“成熟”一词; RabbitMQ在市场上的销售时间仅比Kafka更长(分别为2007年和2011年)。 RabbitMQ和Kafka都是“成熟的”,这意味着它们都被认为是可靠且可扩展的消息传递系统。

消息处理(消息重播)

这是它们之间的主要区别;

与大多数消息系统不同,Kafka中的消息队列是持久的。 发送的数据将被存储,直到经过指定的保留期限(一段时间或大小限制)为止。 该消息会一直保留在队列中,直到超过保留期限/大小限制为止,这意味着该消息一旦被使用就不会被删除。 而是可以多次播放或使用它,该设置可以调整

在RabbitMQ中,消息一直存储到接收应用程序连接并从队列接收消息为止。 客户端可以在收到消息或完全处理完消息后对其进行确认(确认)。 无论哪种情况,一旦消息被确认,就会从队列中删除。

如果您在Kafka中使用重放,请确保以正确的方式和正确的原因使用重放。 重播在有些时候确实很方便,比如你部署的新版本消费者有bug,你需要处理一些或全部的消息的时候。

协议

我还提到“ RabbitMQ支持多种标准化协议,例如AMQP,MQTT,STOMP等”,它本地实现AMQP 0.9.1。 使用标准消息协议,可以用任何基于AMQP的代理替换RabbitMQ代理。

Kafka在TCP / IP之上使用自定义协议在应用程序和群集之间进行通信。 由于Kafka是唯一实现此协议的软件,因此不能简单地将其删除和替换。

RabbitMQ支持不同协议的能力意味着它可以在许多不同的场景中使用。

AMQP的最新版本与官方支持的版本0.9.1完全不同。 RabbitMQ不太可能偏离AMQP 0.9.1。 该协议的1.0版于2011年10月30日发布,但尚未获得开发人员的广泛支持。 可通过插件获得AMQP 1.0。

路由

答案的下一部分是关于路由的,我写道:“ Kafka具有非常简单的路由方法。如果您需要以复杂的方式将消息路由给消费者,RabbitMQ有更好的选择。”

RabbitMQ的主要优势在于能够灵活地路由消息。基于直接或基于正则表达式的路由使消息无需特定代码即可到达特定队列。 RabbitMQ有四个不同的路由选项:直接,主题,扇出和标题交换。直接交换将路由消息发送到所有队列,并与路由队列完全匹配。扇出交换可以将消息广播到绑定到该交换的每个队列。主题方法类似于直接方法,因为它使用路由键,但允许通配符匹配以及精确匹配。有关不同交易所类型的更多信息,请参见此处

Kafka不支持路由。 Kafka主题分为多个分区,每个分区包含不可更改的消息。您可以使用使用者群组和持久性主题来代替RabbitMQ中的路由,在该路由中,您将所有消息发送到一个主题,但是让您的使用者组从不同的偏移量进行订阅。

您可以在Kafka流的帮助下自行创建动态路由,您可以在其中将事件动态路由到主题,但这不是默认功能。

什么时候用RabbitMQ 什么时候用Apache Kafka?

消息优先级

RabbitMQ支持优先级队列,这意味着可以将队列设置为具有一定范围的优先级。 可以在发布时设置每个消息的优先级。 根据消息的优先级,将其放置在适当的优先级队列中。 那么,何时可以使用优先级队列? 下面是一个简单的示例:我们每天都在为托管数据库服务ElephantSQL运行数据库备份。 成千上万的备份事件无顺序添加到RabbitMQ。 客户还可以按需触发备份,如果发生备份,我会向队列中添加一个新的备份事件,但优先级更高。

在Kafka中,不能以优先级发送消息,也不能以优先级顺序发送消息。 无论用户方有多忙,Kafka中的所有消息都按照接收顺序存储和传递。

确认(提交或确认)Acknowledgment (Commit or Confirm)

“确认(Acknowledgment)”是在通信过程之间传递的用于表示确认的信号,即,接收到已发送或已处理的消息。

Kafka和RabbitMQ都支持生产者确认(发布者在RabbitMQ中进行确认),以确保已发布的消息已安全到达代理。

当节点将消息传递给消费者时,它必须决定是否应将消息视为由消费者处理(或至少已接收)。 客户端可以在收到消息时确认消息,也可以在客户端完全处理完消息后确认消息。

RabbitMQ可以考虑将其发送出去后立即发送,也可以等待使用者在收到消息后进行手动确认。

Kafka为分区中的每个消息维护一个偏移量。 提交的位置是已保存的最后一个偏移量。 如果该进程失败并重新启动,这是它将恢复到的偏移量。 Kafka中的使用者可以定期自动提交偏移,也可以选择手动控制此提交的位置。

Kafka跟踪消费在不同版本的Apache Kafka中没有什么不同的地方。 在早期版本中,消费者跟踪偏移量。

当RabbitMQ客户端无法处理消息时,它也可以对消息进行否定(nack)(否定确认,negative acknowledgement)。 该消息将被返回到它来自的队列,就好像它是一条新消息一样。 这在用户方暂时故障的情况下很有用。

如何处理队列?

RabbitMQ的队列在空时最快,而Kafka则用于保存和分发大量消息。 Kafka可以以很少的开销保留大量数据。

尝试RabbitMQ的人可能不知道功能惰性队列(lazy queues)。 惰性队列是将消息自动存储到磁盘的队列,从而最大程度地减少了RAM使用量,但延长了吞吐量时间。 根据我们的经验,惰性队列会创建具有更好的预测性能的更稳定的群集。 如果您一次发送大量消息(例如,处理批处理作业),或者您认为消费者无法始终跟上发布者的速度,则建议您启用惰性队列。

伸缩(Scaling)

伸缩是指增加或减少系统容量的过程。 RabbitMQ和Kafka可以以不同的方式扩展,您可以调整使用者的数量,代理的功能或在系统中添加更多节点。

消费者伸缩(CONSUMER SCALING)

在 RabbitMQ 中,如果你生产的速度比你消费的速度快,您的队列将开始增长,并可能最终收到数百万条消息,最终导致RabbitMQ内存不足。在这种情况下,您可以扩展正在处理(消费)消息的消费者的数量。在RabbitMQ的每个队列可以有很多消费者,而这些消费者都可以“竞争”来消费从队列中的消息。消息处理遍及所有活跃的消费者,因此可以通过简单地添加和删除消费者来在RabbitMQ中进行伸缩。

在Kafka中,分散消费者的方法是使用主题分区,其中消费者群组中的每个使用者专用于一个或多个分区。 您可以使用分区机制通过业务**(例如,通过用户标识,位置等)向每个分区发送不同的消息集。

伸缩 broker(SCALING BROKER)

在*的答案中,我写道: “ Kafka是从头开始构建的,考虑到了水平缩放(添加更多机器),而RabbitMQ主要是为垂直缩放(添加更多功率)而设计的”。 答案的这一部分将提供有关运行Kafka或RabbitMQ的计算机的信息。

在RabbitMQ中,水平缩放并不总是可以为您提供更好的性能。 垂直缩放(增加功率)可达到最佳性能。 在RabbitMQ中可以进行水平缩放,但这意味着您必须在节点之间设置集群,这可能会减慢体系速度。

在Kafka中,您可以通过向集群添加更多节点或向主题添加更多分区来进行扩展。 有时比在RabbitMQ中添加CPU或内存到现有计算机中要容易得多。

许多人和博客,包括Confluent,都在谈论Kafka在扩展方面有多么出色。 可以肯定的是,Kafka可以比RabbitMQ进一步扩展,因为购买机器的能力总是存在限制。 但是,在这种情况下,我们需要记住使用broker的原因。 您可能有一些大规模的消息量,Kafka和RabbitMQ都可以毫无问题地支持,并且我们大多数人都处理不到让RabbitMQ空间不足的规模。

日志压缩

日志压缩策略是Apache Kafka中值得一提的功能,而RabbitMQ中不存在此功能。 日志压缩可确保Kafka始终为单个主题分区的队列中的每个消息键保留最后的已知值。 Kafka只是保留消息的最新版本,并使用相同的**删除较旧的版本。

日志压缩可以看作是将Kafka用作数据库的一种方式。 您将保留期限设置为“永久”或对某个主题启用日志压缩,因此,数据将永久存储。

当我们显示正在运行的数千个集群中一个集群的最新状态时,便是使用日志压缩的一个示例。 我们存储最终状态,而不是存储集群是否一直在响应。 最新信息立即可用,例如队列中当前有多少消息。

监控方式(Monitoring)

RabbitMQ具有易于使用的界面,可让您从Web浏览器监视和处理RabbitMQ服务器。 除其他事项外,可以在浏览器中处理(创建,删除和列出)队列,连接,通道,交换,用户和用户权限,并且您可以监视消息速率并手动发送/接收消息。

对于Kafka,我们有许多用于监视的开源工具,还有一些商业工具,它们提供管理和监视功能。 可在此处找到有关Kafka的各种监视工具的信息。

PUSH or PULL

消息从RabbitMQ推送(push)到消费者。 重要的是配置一个预取限制,以防止使用者不知所措(如果消息到达队列的速度比使用者处理它们的速度快)。 消费者也可以从RabbitMQ提取(pull)消息,但不建议这样做。 另一方面,Kafka使用拉(pull)模型(如前所述),在此模型中,消费者从给定偏移量中请求一批消息

License

RabbitMQ最初是由Rabbit Technologies Ltd.创建的。该项目于2013年5月成为Pivotal Software的一部分。RabbitMQ的源代码是根据Mozilla Public License发布的。许可证从未更改(截至2019年11月)。

Kafka最初是在LinkedIn上创建的。它被授予开源状态,并于2011年传递给Apache基金会。Apache Kafka受Apache 2.0许可证的保护。经常与Kafka结合使用的某些组件由另一个称为Confluent社区许可证的许可证涵盖,例如REST代理,架构注册表和KSL。该许可证仍然允许人们*下载,修改和重新分发代码(非常类似于Apache 2.0),但是它不允许任何人以SaaS产品的形式提供该软件。

这两个许可证都是免费的开源软件许可证。如果Kafka再次将许可证更改为更严格的许可证,这就是RabbitMQ的优势,因为它可以轻松地由另一个AMQP经纪人替换,而Kafka不能。

复杂性

我个人认为,RabbitMQ入门比较容易,并且发现使用起来很容易。 正如我们的客户所说;

“我们没有花任何时间来学习RabbitMQ,它已经工作了很多年。在DoorDash高速增长的过程中,它无疑降低了运营成本。” 刘兆邦,Doordash

我认为,Kafka的体系结构带来了更多的复杂性,因为它从一开始就包含更多的概念,例如主题/分区/消息偏移量等。 您必须熟悉消费者群体以及如何处理偏移量。

作为Kafka和RabbitMQ的使用者,我们认为处理Kafka中的故障要复杂一些。 恢复或修复某些东西的过程通常比较耗时,而且更加混乱。

Kafka 生态系统

Kafka不仅是 broker,还是一个流媒体平台,并且有许多可用的工具可以轻松地与主发行版之外的Kafka集成。 Kafka生态系统由Kafka Core,Kafka Streams,Kafka Connect,Kafka REST Proxy和架构注册表组成。请注意,Kafka生态系统的大多数其他工具都来自Confluent,而不是Apache的一部分。

使用所有这些工具的好处是,您可以在需要编写一行代码之前配置一个庞大的系统。

Kafka Connect可让您将其他系统与Kafka集成。您可以添加一个数据源,该数据源允许您使用该数据源中的数据并将其存储在Kafka中(或相反),并将主题中的所有数据发送到另一个系统进行处理或存储。使用Kafka Connect有很多可能性,而且由于已经有很多连接器可用,因此上手起来很容易。

Kafka REST代理使您有机会从集群接收元数据,并通过简单的REST API生成和使用消息。可以从“控制面板”为群集轻松启用此功能。

常见用例-RabbitMQ vs Apache Kafka

关于一个系统可以做什么或不能做什么,有很多信息。 这是两个主要的用例,它们描述了我和我们的许多客户如何思考并决定要使用哪个系统。 当然,我们也看到了这样的情况:客户构建了一个系统,应该使用一个系统代替另一个系统。

RabbitMQ的用例

通常,如果您想要一个简单/传统的发布/订阅消息代理,显而易见的选择是RabbitMQ,因为它很可能会比您需要的扩展规模更大。 如果我的需求足够简单,可以处理通过通道/队列进行的系统通信,并且不需要保持(retention)和流式传输,那么我会选择RabbitMQ。

在两种情况下,我会选择RabbitMQ。 对于长时间运行的任务,当我需要运行可靠的后台作业时。 为了在应用程序之间以及应用程序之间进行通信和集成,即作为微服务之间的中间人,系统只需通知系统的另一部分即可开始执行任务,例如在网上商店中进行订单处理(下订单,更新订单状态) ,发送订单,付款等)。

长期任务(LONG-RUNNING TASKS)

消息队列启用异步处理,这意味着它们允许您将消息放入队列而无需立即对其进行处理。 RabbitMQ非常适合长时间运行的任务。

可以在我们的RabbitMQ初学者指南中找到一个示例,该指南遵循经典方案,其中Web应用程序允许用户将信息上载到网站。 该站点将处理此信息,生成PDF,然后将其通过电子邮件发送给用户。 在此示例情况下,完成任务需要花费几秒钟,这是将使用消息队列的原因之一。

我们的许多客户都将RabbitMQ队列用作事件总线,使Web服务器可以快速响应请求,而不必*现场执行计算量大的任务。

以Softonic为例,他们https://www.cloudamqp.com/blog/2019-01-18-softonic-userstory-rabbitmq-eventbased-communication.html在支持1亿用户的基于事件的微服务架构中使用RabbitMQ 一个月。

微服务架构中的中间人(MIDDLEMAN IN A MICROSERVICE ARCHITECTURES)

RabbitMQ还被许多客户用于微服务体系结构,在该微服务体系结构中,RabbitMQ用作在应用程序之间进行通信的一种方式,从而避免了瓶颈传递消息。

例如,您可以阅读Parkster(数字停车服务)如何通过使用RabbitMQ将系统分解为多个微服务。

MapQuest是一项大型定向服务,每月支持2310万唯一移动用户。 地图更新发布到位于组织和公司中的个人设备和软件。 这里RabbitMQ主题分布在适当数量的队列中。 数以千万计的用户通过该框架接收准确的企业级地图信息。

Apache Kafka的用例

通常,如果您想要一个用于存储,读取(重新读取)和分析流数据的框架,请使用Apache Kafka。 对于经过审核的系统或需要永久存储消息的系统而言,它是理想的选择。 这些也可以分为两个主要用例,用于分析数据(跟踪,提取,记录,安全性等)或实时处理。

数据分析:跟踪,摄取,记录,安全(DATA ANALYSIS: TRACKING, INGESTION, LOGGING, SECURITY)

在所有这些情况下,都需要收集,存储和处理大量数据。 需要深入了解数据,提供搜索功能,审核或分析大量数据的公司证明使用Kafka是合理的。

据Apache Kafka的创建者称,Kafka的最初用例是跟踪网站活动,包括页面浏览量,搜索,上传或用户可能采取的其他操作。 这种活动跟踪通常需要非常高的吞吐量,因为会为每个操作和每个用户生成消息。 其中许多活动-实际上是所有系统活动-都可以存储在Kafka中并根据需要进行处理。

数据生产者只需要将数据发送到单个位置,而大量后端服务就可以根据需要使用数据。 主要的分析,搜索和存储系统已与Kafka集成。

Kafka可用于将大量信息流式传输到存储系统,而如今,硬盘驱动器空间已不是一笔大开销。

实时处理(REAL-TIME PROCESSING)

Kafka充当高吞吐量分布式系统; 源服务将数据流推送到目标服务中,以实时将其拉出。

Kafka可用于实时处理许多生产者且具有少量消费者的系统。 即金融IT系统监视库存数据。

从Spotify到荷兰合作银行的流媒体服务通过Kafka实时发布信息。 实时处理高吞吐量的能力为应用程序提供了支持,使这些应用程序比以往任何时候都功能强大。

CloudAMQP在服务器设置的自动化过程中使用RabbitMQ,但是在发布日志和指标时我们使用了Kafka。

RabbitMQ Apache Kafka
简述 RabbitMQ是可靠,成熟的通用消息代理 Apache Kafka是针对高入口数据流和重播进行了优化的消息总线
主要用途 消息队列,用于在应用程序之内和之间进行通信和集成。对于长时间运行的任务,或需要运行可靠的后台作业的情况。 用于存储,读取(重新读取)和分析流数据的框架。最适合
License Open Source: Mozilla Public License Open Source: Apache License 2.0
开发语言 Erlang Scala (JVM)
第一个发行版本 2007 2011
持久化 持久化消息,直到在消费者确认后将其丢弃 可选保留时长的持久化消息
Replay(重播) NO YES
路由 灵活的路由将消息路由给消费者 不支持灵活的路由,必须通过单独的主题完成
消息优先级 支持 不支持
监控方式 可用内置的UI 通过第三方工具(例如在CloudKarafka上部署或通过Confluent部署)可用
语言支持 支持大多数语言 支持大多数语言
安全认证 支持标准身份验证和OAuth2 支持Kerberos,OAuth2和标准身份验证