如果你在问自己,Apache Kafka是否比RabbitMQ更好,或者RabbitMQ是否比Apache Kafka更可靠,我想就此打住你。本文将从更广阔的角度讨论这两个问题。它的重点是两个系统所提供的功能,并将指导您在何时使用哪个系统做出正确的决定。
网络上的一些文章让Apache Kafka在RabbitMQ面前大放异彩,而另一些则恰恰相反。我们中的很多人都可以承认自己听了炒作,和群众一起跑。我觉得重要的是要知道,决定是否使用RabbitMQ或Kafka取决于您的项目的需求,只有在合适的场景中使用了正确的设置,才能进行真正的比较。
本文使用的术语包括:
消息队列是RabbitMQ中的一个队列,Kafka中的这个“队列”被称为日志,但是为了简化本文中的信息,我将引用队列,而不是一直切换到“log
”。
在Kafka中,一条消息通常被称为一条记录,但是为了简化这里的信息,我将再次引用消息。
当我在Kafka中写一个topic
主题时,你可以把它看作是消息队列中的分类。Kafka主题被划分为分区,分区中包含的记录以不可更改的顺序排列。
这两个系统都通过队列或主题在生产者和消费者之间传递消息。消息可以包含任何类型的信息。例如,它可以有关于某个网站上发生的事件的信息,也可以是触发另一个应用程序上事件的简单文本消息。
这种系统是连接不同组件、构建微服务、实时数据流或将工作传递给远程工作者的理想选择。
根据Confluent的数据,超过三分之一的财富500强公司使用ApacheKafka。各大行业也依赖RabbitMQ,如Zalando、WeWork、Wunderlist和Bloomberg。
【图片】
什么时候用Kafka? 什么时候用拉比MQ?
RabbitMQ是一个可靠、成熟、通用的消息代理,它支持多种协议,如AMQP、MQTT、STOMP等等。RabbitMQ可以处理高吞吐量。它的一个常见用例是处理后台作业或充当微服务之间的消息代理。Kafka是一种消息总线,针对高入口数据流和重放进行了优化。Kafka可以看作是一个持久的消息代理,应用程序可以在其中处理和重新处理磁盘上的流数据。
关于“成熟”一词;RabbitMQ上市的时间比Kafka长(分别是2007年和2011年)。RabbitMQ和Kafka都是“成熟的”,这意味着它们都被认为是可靠和可扩展的消息传递系统。
消息处理(消息重放)
这是他们之间的主要区别;与大多数消息传递系统不同,Kafka中的消息队列是持久的。发送的数据将一直存储到指定的保留期(一段时间或大小限制)过后。消息将一直保留在队列中,直到超过保留期/大小限制,这意味着消息一旦被使用,就不会被删除。相反,它可以被重放或使用多次,这是一个可以调整的设置。
在RabbitMQ中,消息被存储,直到接收应用程序连接并从队列中接收消息。客户机可以在收到消息时确认消息,也可以在客户机已完全处理消息时确认消息。在这两种情况下,一旦消息被确认,它就会从队列中删除。
如果你在Kafka中使用重播,请确保你以正确的方式和理由使用它。将一个事件重放多次,而该事件只发生一次;如果您碰巧多次保存客户订单,则在大多数使用场景中都不理想。当使用者中存在需要部署更新版本的bug,并且需要重新处理部分或全部消息时,重播确实会派上用场。
协议
RabbitMQ支持几个标准化的协议,比如AMQP、MQTT、STOMP等,在这里它本机实现了amqp0.9.1。标准化消息协议的使用允许您用任何基于AMQP的代理替换RabbitMQ代理。
Kafka在TCP/IP之上使用一个定制的协议来在应用程序和集群之间进行通信。卡夫卡不能简单地被删除和替换,因为它是实现这个协议的唯一软件。
RabbitMQ支持不同协议的能力意味着它可以在许多不同的场景中使用。
AMQP的最新版本与官方支持的版本0.9.1有很大的不同。RabbitMQ不太可能偏离AMQP 0.9.1。该协议的1.0版本于2011年10月30日发布,但尚未获得开发人员的广泛支持。AMQP1.0通过插件提供。
路由
Kafka有一个非常简单的路由方法。如果您需要以复杂的方式将消息路由到消费者,RabbitMQ有更好的选择。
RabbitMQ的主要优点是能够灵活地路由消息。直接或基于正则表达式的路由允许消息到达特定队列而无需额外代码。RabbitMQ有四种不同的路由选择:direct
, topic
, fanout
, header exchanges
。直接交换将消息路由到所有队列,并与称为路由密钥的内容完全匹配。扇出交换可以向绑定到交换的每个队列广播消息。topics方法与direct类似,因为它使用路由密钥,但允许通配符匹配和精确匹配。
Kafka不支持路由;卡夫卡主题被划分为分区,分区中包含的消息以不可更改的顺序排列。您可以使用使用者组和持久主题来替代RabbitMQ中的路由,在RabbitMQ中,您可以将所有消息发送到一个主题,但允许使用者组从不同的偏移量进行订阅。
您可以在Kafka streams的帮助下自己创建动态路由,在Kafka streams中,您可以动态地将事件路由到主题,但这不是默认特性。
消息优先级
RabbitMQ支持称为优先级队列的东西,这意味着可以将队列设置为具有一系列优先级。每个消息的优先级可以在发布时设置。根据消息的优先级,它被放置在相应的优先级队列中。那么,什么时候可以使用优先级队列呢?下面是一个简单的例子:我们每天都在为托管数据库服务ElephantSQL运行数据库备份。数千个备份事件不按顺序添加到RabbitMQ。客户还可以按需触发备份,如果发生这种情况,我会向队列中添加一个新的备份事件,但优先级更高。
在Kafka中,消息不能按优先级发送,也不能按优先级顺序传递。卡夫卡中的所有消息都是按接收顺序存储和传递的,而不管用户端有多忙。
确认是在通信进程之间传递的表示确认的信号,即接收发送或处理的消息。
Kafka和RabbitMQ都支持生产者确认(publisher在RabbitMQ中确认),以确保已发布的消息已安全到达代理。
当节点将消息传递给使用者时,它必须决定该消息是否应该被认为是由使用者处理(或至少是接收)的。客户机可以在收到消息时确认消息,也可以在客户机已完全处理消息时确认消息。
RabbitMQ可以在消息发出后考虑传递消息,或者等待使用者在收到消息时手动确认消息。
Kafka为分区中的每条消息维护一个偏移量。提交的位置是最后保存的偏移量。如果进程失败并重新启动,这就是它将恢复到的偏移量。Kafka中的使用者可以定期自动提交偏移量,也可以选择手动控制提交的位置。
Kafka如何跟踪在不同版本的apachekafka中被消费的内容和没有被消费的内容。在早期版本中,使用者跟踪偏移量。
RabbitMQ客户机也可以在无法处理消息时对消息进行nack(否定确认)。消息将被返回到它来自的队列,就好像它是一个新消息一样;这在用户端出现临时故障时非常有用。
如何处理队列?
RabbitMQ的队列在空的时候是最快的,而Kafka是为保存和分发大量消息而设计的。Kafka以很少的开销保留了大量的数据。
试用RabbitMQ的人可能不知道lazy queues
的特性。延迟队列是消息自动存储到磁盘的队列,从而最小化RAM使用,但延长了吞吐量时间。根据我们的经验,延迟队列创建了一个更稳定的集群,具有更好的预测性能。如果您一次发送大量邮件(例如,处理批处理作业),或者如果您认为您的用户无法始终跟上发布者的速度,建议您启用延迟队列。
缩放比例
缩放是指增加或减少系统容量的过程。RabbitMQ和Kafka可以以不同的方式扩展,您可以调整使用者的数量、代理的能力或向系统中添加更多节点。
消费者规模
如果发布速度比使用RabbitMQ快,那么队列将开始增长,最终可能会出现数百万条消息,最终导致RabbitMQ内存不足。在这种情况下,您可以缩放处理(使用)您的消息的使用者的数量。RabbitMQ中的每个队列可以有许多使用者,这些使用者都可以“竞争”来使用队列中的消息。消息处理分布在所有活动的使用者中,因此可以通过简单地添加和删除使用者来实现RabbitMQ中的放大和缩小。
在Kafka中,分发使用者的方法是使用主题分区,其中组中的每个使用者都专用于一个或多个分区。您可以使用分区机制按业务密钥(例如,按用户id、位置等)向每个分区发送一组不同的消息。
缩放代理
Kafka是从头开始构建的,考虑到了水平缩放(添加更多的机器),而RabbitMQ主要是为垂直缩放(添加更多的功率)而设计的。答案的这一部分是提供有关运行Kafka或RabbitMQ的机器的信息。
在RabbitMQ中,水平扩展并不总是提供更好的性能。通过垂直缩放(增加更多功率)可以获得最佳性能级别。水平扩展在RabbitMQ中是可能的,但这意味着您必须在节点之间设置集群,这可能会减慢您的设置速度。
在Kafka中,可以通过向集群添加更多节点或向主题添加更多分区来扩展。这有时比像RabbitMQ那样将CPU或内存添加到现有机器更容易。
许多人和博客,包括Confluent,都在谈论Kafka在伸缩方面有多么伟大。当然,Kafka可以比RabbitMQ扩展得更远,因为你可以购买的机器的坚固程度总是有限制的。但是,在这种情况下,我们需要记住使用代理的原因。您可能有一个Kafka和RabbitMQ都可以毫无问题地支持的消息卷,而且我们大多数人不会处理RabbitMQ耗尽空间的规模。
日志压缩
Apache Kafka中值得一提的一个特性是日志压缩策略,而RabbitMQ中不存在这个特性。日志压缩确保Kafka始终为单个主题分区的队列中的每个消息键保留最后的已知值。Kafka只需保留最新版本的消息,并用相同的密钥删除旧版本。
日志压缩可以看作是将Kafka用作数据库的一种方法。您将保留期设置为“forever
”,或者对主题启用日志压缩,瞧,数据将永久存储。
我们使用日志压缩的一个例子是,在运行的数千个集群中显示一个集群的最新状态。我们不存储集群是否一直在响应,而是存储最终状态。最新信息立即可用,例如队列中当前有多少条消息。
监测
RabbitMQ有一个用户友好的界面,允许您从web浏览器监视和处理RabbitMQ服务器。除此之外,还可以在浏览器中处理(创建、删除和列出)队列、连接、通道、交换、用户和用户权限,并且可以监视邮件速率和手动发送/接收邮件。
对于Kafka,我们有许多用于监视的开源工具,还有一些商业工具,提供管理和监视功能。关于卡夫卡不同监控工具的信息:https://medium.com/@giorgosmyrianthous/overview-of-ui-monitoring-tools-for-apache-kafka-clusters-9ca516c165bd
推或拉
消息从RabbitMQ推送到使用者。配置预取限制非常重要,这样可以防止消费者无法承受(如果消息到达队列的速度比消费者处理它们的速度快)。消费者也可以从RabbitMQ中提取消息,但不建议这样做。另一方面,Kafka使用pull模型,如前所述,消费者从给定的偏移量请求成批的消息。
许可证
RabbitMQ最初由Rabbit Technologies Ltd.创建。该项目于2013年5月成为Pivotal软件的一部分。RabbitMQ的源代码是在Mozilla公共许可下发布的。许可证从未更改(截至2019年11月)。
Kafka最初创建于LinkedIn。它被授予开源状态,并在2011年被传递给了Apache基金会。ApacheKafka包含在Apache2.0许可证中。通常与Kafka结合使用的一些组件包含在另一个名为Confluent Community license的许可证中,例如Rest Proxy、Schema Registry和KSL。这个许可仍然允许人们自由下载、修改和重新发布代码(非常像Apache2.0),但是它不允许任何人将软件作为SaaS产品提供。
这两个许可证都是免费的开源软件许可证。如果Kafka再次将许可证更改为更严格的许可证,这就是RabbitMQ的优势所在,因为它可以很容易地被另一个AMQP代理替换,而Kafka则不能。
复杂性
就我个人而言,我认为开始使用RabbitMQ更容易,并且发现它很容易使用。正如我们的一位顾客所说;
“我们没有花任何时间学习RabbitMQ,它工作了很多年。在DoorDash的高速增长过程中,这无疑降低了成吨的运营成本。”DoorDash
在我看来,Kafka的架构带来了更多的复杂性,因为它从一开始就包含了更多的概念,比如主题/分区/消息偏移量等。你必须熟悉消费者群体以及如何处理补偿。
作为Kafka和RabbitMQ操作符,我们觉得在Kafka中处理失败要复杂一些。恢复或修复某物的过程通常更耗时,也更混乱。
Kafka生态系统
Kafka不仅仅是一个代理,它是一个流媒体平台,有很多工具可以很容易地与Kafka集成在主发行版之外。Kafka生态系统由Kafka核心、Kafka流、Kafka连接、Kafka REST代理和模式注册表组成。请注意,Kafka生态系统的大多数附加工具都来自Confluent,而不是Apache的一部分。
所有这些工具的好处是,您可以在编写一行代码之前配置一个庞大的系统。
Kafka Connect允许您将其他系统与Kafka集成。您可以添加一个数据源,该数据源允许您使用来自该源的数据并将其存储在Kafka中,或者以其他方式存储,并将主题中的所有数据发送到另一个系统进行处理或存储。使用Kafka Connect有很多可能性,而且很容易开始使用,因为已经有很多可用的连接器。
Kafka REST代理让您有机会从集群接收元数据,并通过简单的restapi生成和使用消息。可以从集群的控制面板轻松启用此功能。
常见用例-RabbitMQ vs Apache Kafka
关于一个系统能做什么,不能做什么,已经有很多信息了。下面是两个主要的用例,描述了我和我们的许多客户是如何思考和决定使用哪个系统的。当然,我们也看到过这样的情况:客户构建了一个系统,其中一个系统应该被使用,而不是另一个。
RabbitMQ的用例
一般来说,如果您想要一个简单/传统的pub-sub消息代理,那么明显的选择是RabbitMQ,因为它很可能比您需要它来扩展的规模更大。如果我的需求足够简单,可以通过通道/队列处理系统通信,并且不需要保留和流式传输,那么我会选择RabbitMQ。
我选择RabbitMQ主要有两种情况;对于长时间运行的任务,当我需要运行可靠的后台作业时。以及应用程序内部和应用程序之间的通信和集成,即作为微服务之间的中间人,系统只需通知系统的另一部分就可以开始处理某项任务,如在网上商店中处理订单(下单、更新订单状态、发送订单、付款等)。
长时间运行的任务
消息队列支持异步处理,这意味着它们允许您将消息放入队列中,而无需立即对其进行处理。RabbitMQ是长时间运行任务的理想选择。
在我们的RabbitMQ初学者指南中可以找到一个例子,它遵循了一个经典场景,其中web应用程序允许用户将信息上载到web站点。该网站将处理这些信息,生成一个PDF文件,并通过电子邮件将其发回给用户。完成本例中的任务需要几秒钟,这也是使用消息队列的原因之一。
我们的许多客户让RabbitMQ队列充当事件总线,允许web服务器快速响应请求,而不是被迫在现场执行计算密集型任务。
以Softonic为例,他们在基于事件的微服务架构中使用RabbitMQ,每月支持1亿用户。
微服务体系结构中的中间人
RabbitMQ还被许多客户用于微服务体系结构,在微服务体系结构中,RabbitMQ作为应用程序之间通信的一种手段,避免了传递消息的瓶颈。
MapQuest是一项大方向服务,每月支持2310万独特的移动用户。地图更新将发布到组织和公司中的个人设备和软件。这里RabbitMQ主题分布在适当数量的队列上。数以千万计的用户通过该框架获得准确的企业级地图信息。
Apache Kafka的用例
一般来说,如果您想要一个用于存储、读取(重读)和分析流数据的框架,请使用Apache Kafka。它非常适合被审计的系统或需要永久存储消息的系统。这些还可以分解为两个主要用例,用于分析数据(跟踪、摄取、日志记录、安全性等)或实时处理。
数据分析:跟踪、摄取、记录、安全
在所有这些情况下,都需要收集、存储和处理大量数据。那些需要深入了解数据、提供搜索功能、对大量数据进行审计或分析的公司,就有理由使用卡夫卡。
据Apache Kafka的创建者称,Kafka最初的用例是跟踪网站活动,包括页面浏览、搜索、上传或用户可能采取的其他操作。这种活动跟踪通常需要非常高的吞吐量,因为消息是为每个操作和每个用户生成的。其中许多活动(实际上是所有系统活动)都可以存储在Kafka中,并根据需要进行处理。
数据生产者只需要将其数据发送到一个地方,而大量后端服务可以根据需要使用数据。主要的分析、搜索和存储系统都与Kafka集成。
Kafka可以用来将大量的信息流到存储系统,而现在硬盘空间并不是一个大的开销。
实时处理
Kafka是一个高吞吐量的分布式系统;源服务将数据流推送到实时拉入它们的目标服务中。
Kafka可以用于系统处理许多生产者在实时与少数消费者;例如金融IT系统监控股票数据。
Spotify到荷兰合作银行的流媒体服务通过Kafka实时发布信息。实时处理高吞吐量的能力增强了应用程序的能力,使这些应用程序比以往任何时候都更强大。
CloudAMQP在服务器设置的自动化过程中使用RabbitMQ,但是我们在发布日志和度量时使用了Kafka。
原文链接:https://www.cloudamqp.com/blog/when-to-use-rabbitmq-or-apache-kafka.html
除特别注明外,本站所有文章均为老K的Java博客原创,转载请注明出处来自https://javakk.com/1920.html
暂无评论