文章目录
- 一、kafka和rabbitmq全面对比分析
-
- [1.1 简介](#1.1 简介)
- [1.2 kafka和rabbitmq全面对比分析](#1.2 kafka和rabbitmq全面对比分析)
- [1.3 影响因素](#1.3 影响因素)
- 二、RabbitMQ、Kafka主要区别
-
- [2.1 详解/主要区别](#2.1 详解/主要区别)
-
- [2.1.1 设计目标和适用场景](#2.1.1 设计目标和适用场景)
- [2.1.2 架构模型方面](#2.1.2 架构模型方面)
- [2.1.3 吞吐量和性能](#2.1.3 吞吐量和性能)
- [2.1.4 消息存储和持久化](#2.1.4 消息存储和持久化)
- [2.1.5 消息传递保证](#2.1.5 消息传递保证)
- [2.1.6 集群负载均衡方面](#2.1.6 集群负载均衡方面)
- [2.1.7 生态系统和社区支持](#2.1.7 生态系统和社区支持)
- [2.2 网上介绍较少的](#2.2 网上介绍较少的)
-
- [2.2.1 消费者端拉取消息的方式不同](#2.2.1 消费者端拉取消息的方式不同)
- [2.2.2 消息被处理完后的处理方式不同](#2.2.2 消息被处理完后的处理方式不同)
- [2.2.3 生产者发送消息到broker的方式不同](#2.2.3 生产者发送消息到broker的方式不同)
- [2.2.4 扩展性和分布式特性](#2.2.4 扩展性和分布式特性)
- [2.2.5 集群(了解即可,无需掌握)](#2.2.5 集群(了解即可,无需掌握))
- [2.3 总结](#2.3 总结)
- 三、Kafka、RabbitMQ、RocketMQ区别
-
- [3.1 语言与开发背景](#3.1 语言与开发背景)
- [3.2 吞吐量与性能](#3.2 吞吐量与性能)
- [3.3 可靠性与容错性](#3.3 可靠性与容错性)
- [3.4 使用场景](#3.4 使用场景)
- [3.5 其他特性](#3.5 其他特性)
RabbitMQ和Kafka是两种流行的消息传递系统,它们在多个方面存在显著的差异。
- 我们在开发中可能会遇到以下情况:有个xx需求,我应该用Kafka还是RabbitMQ?
- 包括面试时也会经常被问到:Kafka、RabbitMQ有什么区别,为什么A项目选用Kafka、而B项目选用RabbitMQ?
总得来说,我们需要掌握 RabbitMQ 和 Kafka 的区别、适用于什么场景、以及各自的优劣。
一、kafka和rabbitmq全面对比分析
1.1 简介
- kafka是apache开源的消息队列顶级项目之一,在大数据场景下使用较多,由linkedin开源,目前社区活跃,全球较多组织开始使用kafka来进行数据交换。kafka采用mq结构,broker有part分区的概念
- RabbitMQ是流行的开源消息队列系统,用erlang语言开发。RabbitMQ是AMQP(Advanced Message Queuing Protocol,高级消息队列协议)的标准实现。RabbitMQ的broker由Exchange、Binding、queue组成。
1.2 kafka和rabbitmq全面对比分析
对比项 | kafka | rabbitmq |
---|---|---|
开发语言 | scala,Java | erlang |
是否支持多租户 | 2.x.x支持多租户 | 支持多租户 |
是否支持topic优先级 | 不支持 | 支持 |
是否支持消息全局有序 | 不支持 | 支持 |
是否支持消息分区有序 | 支持 | 支持 |
是否内置监控 | 无内置监控 | 内置监控 |
是否支持多个生产者 | 一个topic支持多个生产者 | |
是否支持多个消费者 | 一个topic支持多个消费者(一个消费者可消费多个分区,一个分区可被多个消费组消费,但同一消费组内仅能有一个消费者同时消费1个分区) | |
是否支持一个分区多个消费者 | 不支持 | 不支持 |
是否支持JMX | 支持 | 不支持(非java语言编写) |
是否支持加密 | 支持 | 支持 |
消息队列协议支持 | 仅支持自定义协议 | 支持AMQP、MQTT、STOMP协议 |
客户端语言支持 | 支持多语言客户端 | 支持多语言客户端 |
是否支持消息追踪 | 不支持消息追踪 | 支持消息追踪 |
是否支持消费者推模式 | 不支持消费者推模式 | 支持消费者推模式 |
是否支持消费者拉模式 | 支持消费者拉模式 | 支持消费者拉模式 |
是否支持广播消息 | 支持广播消息 | 支持广播消息 |
是否支持消息回溯 | 支持消息回溯,因为消息持久化,消息被消费后会记录offset和timstamp | 不支持,消息确认被消费后,会被删除 |
是否支持消息数据持久化 | 支持消息数据持久 | 支持消息数据持久 |
是否支持消息堆积 | 支持消息堆积,并批量持久化到磁盘 | 支持阈值内的消息对接,无法支持较大的消息堆积 |
是否支持流量控制 | 支持控制用户和客户端流量 | 支持生产者的流量控制 |
是否支持事务性消息 | 支持 | 不支持 |
元数据管理 | 通过zookeeper进行管理 | 支持消息数据持久 |
默认服务端口 | 9092 | 5672 |
默认监控端口 | kafka web console 9000;kafka manager 9000; | 15672 |
网络开销 | 相对较小 | 相对较大 |
内存消耗 | 相对较小 | 相对较大 |
cpu消耗 | 相对较大 | 相对较小 |
kafka支持一个消费者可消费多个分区,同一分区仅支持同一消费组下一个消费者,但支持多个消费组消费。
在公司项目中,一般消息量都不大的情况下,推荐大家可以使用 RabbitMQ。消息量起来了可以考虑切换到 Kafka,但是也要根据公司内部对两种 MQ 的熟悉程度来进行选择,避免 MQ 出现问题时无法及时处理。
1.3 影响因素
- 架构设计:RabbitMQ 的架构是专为复杂的消息路由而设计,RabbitMQ 使用推送模型。生产者可以使用不同的路由规则向使用者发送消息。Kafka 的架构是专为实时、高吞吐量的流处理场景设计,是一种基于分区的设计。Kafka 使用拉取模型,生产者向使用者订阅的主题和分区发布消息。
- 性能:Kafka 的扩展方式是水平扩展(horizontal scaling),即通过增加集群中的节点数来提高性能和容量。因此在处理大容量、高吞吐量和实时数据流上性能优势很大,它每秒能够处理数百万个事件,并且可以处理大量数据。RabbitMQ 的扩展方式是垂直扩展(vertical scaling),即通过增加单个节点的硬件资源来提高性能和容量,因此它受到单个节点性能和容量的瓶颈,在性能方面是不如 Kafka 的。
- 消息延迟:RabbitMQ 使用推送模型(push model),即交换机将消息推送到队列,然后队列将消息推送到消费者,这样可以减少消息在队列中的等待时间,降低延迟;Kafka 使用拉取模型(pull model),即生产者将消息发布到主题,然后消费者从主题拉取消息,这样可以增加消费者对消息的控制力,提高吞吐量,但也会增加延迟。因此在在延迟方面 Kafka 是不如 RabbitMQ 的。
- 消息顺序:Kafka 保证了同一个分区(partition)内的消息是有序的,即按照生产者发送的顺序来存储和消费。但是不同分区之间的消息是无序的,即不能保证跨分区的消息按照全局顺序来处理。 RabbitMQ 保证了同一个队列内的消息是有序的,即按照先进先出(FIFO)的原则来存储和消费。但是不同队列之间的消息是无序的,即不能保证跨队列的消息按照全局顺序来处理。
- 容灾机制:Kafka 通过副本(replica)机制来保证数据的可靠性,即每个主题可以有多个副本分布在不同的节点(broker)上,如果某个节点发生故障,可以自动切换到其他节点继续提供服务。 RabbitMQ 通过镜像(mirror)机制来保证数据的可靠性,即每个队列可以有多个镜像分布在不同的节点上,如果某个节点发生故障,可以自动切换到其他节点继续提供服务。
- 消息持久化:Kafka 将数据持久化到磁盘中,并且支持数据压缩和批量传输,以提高性能和节省空间。Kafka 可以支持 TB 级别甚至 PB 级别的数据存储,并且可以快速地重放历史数据。RabbitMQ 将数据缓存在内存中,并且支持消息确认和事务机制,以提高可靠性和一致性。RabbitMQ 也可以将数据持久化到磁盘中,但是会降低性能和吞吐量。RabbitMQ 更适合处理小规模且实时性较高的数据。
- 消息删除:RabbitMQ 支持消费者确认机制(consumer acknowledgement),即消费者在接收并处理完消息后向队列发送确认信号,队列才会删除该消息,这样可以保证消息的可靠传递;Kafka 不支持消费者确认机制,而是由消费者将消息附加到日志文件中,自己维护一个偏移量来记录已经消费过的消息,主题不会删除任何消息,该日志文件将一直留存到其保留期到期,除非达到预设的保留期限或大小限制。这样消费者可以在规定的时间内随时重新处理流式传输中的历史数据。
- 消息路由:RabbitMQ 支持多种交换机类型,例如直接交换机(direct exchange)、主题交换机(topic exchange)、扇形交换机(fanout exchange)等,以实现不同的消息路由和分发策略;Kafka 不支持消息过滤,而是通过主题和分区来进行消息分类和分发。
- 易用性:RabbitMQ 的安装和配置相对简单,只需要下载安装包并运行即可,也可以通过命令行或图形界面来管理和监控服务器状态;Kafka 的安装和配置相对复杂,需要依赖于 ZooKeeper 服务来协调集群状态,并且需要手动调整一些参数来优化性能和可靠性。因此在易用性上 RabbitMQ 是更简单的。
二、RabbitMQ、Kafka主要区别
2.1 详解/主要区别
2.1.1 设计目标和适用场景
- RabbitMQ :RabbitMQ是一个传统的消息队列系统,采用了基于消息队列的发布-订阅模型
- 设计目标:RabbitMQ的设计目标是确保消息的可靠传递,并提供多种消息传递协议的支持
- 应用场景 :通常用于实时的、对可靠性要求较高 的消息传递上
- 中小项目,项目消息量小、吞吐量不高、对延时敏感
- 遗留应用,如需要与旧系统或第三方系统进行集成或通信
- 复杂路由,如需要根据不同的规则或条件来分发或过滤消息
- 延迟敏感,对于消费者处理消息的及时性有非常高的要求
- Kafka :Kafka是一个分布式事件流平台,采用了发布-订阅日志模型
- 设计目标:Kafka的设计目标是提供高吞吐量和持久化存储,支持事件溯源、数据湖等长期存储需求
- 应用场景 :主要用于处理活跃的流式数据,特别适用于大数据量的数据处理场景 。
- 跟踪高吞吐量的活动,如网站点击、应用日志、传感器数据等
- 事件溯源,Kafka 保存着所有历史消息,可以用于事件回溯和审计
- 流式处理,如实时分析、实时推荐、实时报警等
- 日志聚合,如收集不同来源的日志并统一存储和分析
2.1.2 架构模型方面
producer,broker,consumer
- RabbitMQ:
- 以broker为中心,有消息的确认机制(这里的确认机制指的是客户端消费消息的时候)
- broker与consumer交互方式:rabbitmq采用push的方式
- kafka:
- 以consumer为中心,无消息的确认机制(这里的确认机制指的是客户端消费消息的时候)
- broker与consumer交互方式:kafka采用pull的方式
kafka和rabbitMQ都有发送到Broker的确认机制。
2.1.3 吞吐量和性能
- RabbitMQ:支持消息的可靠传递,支持事务,不支持批量操作,基于存储的可靠性的要求存储可以采用内存或硬盘,吞吐量小,在处理大量消息时可能会受限于单一队列的性能瓶颈。如果需要持久化,会采用实时存储
- kafka:内部采用消息的批量处理,数据的存储和获取是本地磁盘顺序批量操作,消息处理的效率高,吞吐量高,这得益于其分布式架构、分区机制以及批量处理等技术。定时持久化存储,非实时持久化储存
2.1.4 消息存储和持久化
- RabbitMQ:RabbitMQ通常保留消息一段时间,然后将其删除。虽然它也支持消息的持久化,但主要是为了确保消息在传递过程中的可靠性,而不是为了长期存储。
- Kafka:Kafka以持久化日志的方式存储消息,允许消息长时间保留。这种设计使得Kafka非常适合用于需要长期存储和回溯消息的场景。
2.1.5 消息传递保证
- RabbitMQ:RabbitMQ提供不同级别的消息传递保证,包括至少一次传递、至多一次传递和确切一次传递。这些保证机制可以根据应用的需求进行配置。
- Kafka:Kafka提供了强大的消息保证,确保消息的持久性、顺序性和可靠性传递。Kafka的分区和副本机制使得即使在节点故障的情况下,也能保证消息的不丢失。
2.1.6 集群负载均衡方面
- RabbitMQ:本身不支持负载均衡,需要loadbalancer的支持。即指定存到哪个broker就是哪个broker
- kafka:采用zookeeper对集群中的broker、consumer进行管理,可以注册topic到zookeeper上,通过zookeeper的协调机制,producer保存对应的topic的broker信息,可以随机或者轮询发送到broker上,producer可以基于语义指定分片,消息发送到broker的某个分片上。即如果不指定分片,就会默认存到master的分片上,然后再同步到其他的分片
2.1.7 生态系统和社区支持
- RabbitMQ:RabbitMQ有一个成熟的生态系统,包括多种客户端库和插件,适用于各种编程语言和应用场景。它拥有广泛的用户群体和活跃的社区支持。
- Kafka:Kafka同样拥有一个庞大的生态系统,特别适用于大规模数据处理和日志管理。Kafka也是Apache软件基金会的一部分,得到了广泛的社区支持和维护。
2.2 网上介绍较少的
2.2.1 消费者端拉取消息的方式不同
- RabbitMQ:采用push的方式,当消息到达队列后,会将消息推到消费者端
- kafka:采用pull的方式,当消息到达队列后,消费者端需要手动从队列拉取消息
2.2.2 消息被处理完后的处理方式不同
- RabbitMQ:被消费者端确认消费了的消息会被从磁盘删除掉
- kafka:消息被消费掉依然保存在磁盘中
2.2.3 生产者发送消息到broker的方式不同
- RabbitMQ:当为主从集群的时候,生产者连接到谁,发送消息就到对应的机器上,其他机器只是存储元数据。消费者连接时,只需要连接任意集群中的任意一台服务器,获取数据时都可以通过元数据经过路由到达实际存储队列消息的那台服务器
- kafka:当生产者发送消息时,必须发送到master分片所在的机器。为了实现这一个功能,kafka在连接集群时,只要连接到任意一台或多台服务器,就可以知道整个集群的情况,其中包含了集群所有机器的ip地址,分片的信息
2.2.4 扩展性和分布式特性
- RabbitMQ:RabbitMQ可以通过集群来水平扩展,但在某些情况下,水平扩展可能不够灵活。它支持多种交换机类型和绑定选项,使得消息可以在多个路由路径中进行传递。
- Kafka:Kafka是天生分布式的,易于水平扩展。它可以在不断增加的负载下轻松添加新的节点,并且支持多个生产者和消费者同时工作。Kafka的分区机制使得消息可以均匀分布在多个节点上,从而提高了系统的整体性能。
2.2.5 集群(了解即可,无需掌握)
- RabbitMQ
- 队列同步发起方(Rabbit使用的镜像集群,非默认的主从集群):镜像队列同步时,由主队列向镜像队列发起
- 副本同步限制:副本队列可以落后主队列很多
- 副本同步对性能的影响(Rabbit使用的镜像集群,非默认的主从集群):新节点加入时,如果ha-sync-mode=manual,则不会手动同步镜像到新节点。如果ha-sync-mode=automatic时,会自动同步到新节点中。在同步新节点时,主节点不会再接收生产者的消息,也不会push消息到消费者,就是一种stop-the-world的状态。如果存量消息过多,则会导致生产者和消费者请求超时,可以使用设置重试规则解决
- Kafka
- 队列同步发起方(Rabbit使用的镜像集群,非默认的主从集群):副本同步时,副本分片由副本分片向主分片发起同步
- 副本同步限制:副本分片只能落后replica.lag.time.max.ms的时间内(ISR),如果超过这个时间,副本分片会被删除掉
- 副本同步对性能的影响(Rabbit使用的镜像集群,非默认的主从集群):新的节点加入,会主动从主分区拉取数据,等待数据拉取完成(不包含未提交的,只包含所有已提交数据)后才把该节点加入到集群中
2.3 总结
RabbitMQ和Kafka在设计目标、消息存储、吞吐量、扩展性、消息传递保证以及生态系统等方面都存在显著的差异。选择哪个系统取决于具体的应用场景和需求。如果需要传递实时数据、低延迟和简单 的队列模型,RabbitMQ可能更适合;如果处理大量事件流、需要持久化和高吞吐量,并且希望构建大规模的分布式系统,那么Kafka可能更适合。
- rabbit为了更高的灵活性和信息安全性,放弃了吞吐量
- kafka为了更多的吞吐量,选择了速度,放弃了部分安全性
实际场景选择:在实际生产应用中,通常会使用kafka作为消息传输的数据管道,rabbitmq作为交易数据作为数据传输管道,主要的取舍因素则是是否存在丢数据的可能;rabbitmq在金融场景中经常使用,具有较高的严谨性,数据丢失的可能性更小,同事具备更高的实时性;而kafka优势主要体现在吞吐量上,虽然可以通过策略实现数据不丢失,但从严谨性角度来讲,大不如rabbitmq;而且由于kafka保证每条消息最少送达一次,有较小的概率会出现数据重复发送的情况
在公司项目中,一般消息量都不大的情况下,推荐大家可以使用 RabbitMQ。消息量起来了可以考虑切换到 Kafka,但是也要根据公司内部对两种 MQ 的熟悉程度来进行选择,避免 MQ 出现问题时无法及时处理。
三、Kafka、RabbitMQ、RocketMQ区别
Kafka、RabbitMQ、RocketMQ都是目前广泛使用的消息队列系统,它们在语言、吞吐量、可靠性、使用场景等方面存在一些明显的区别。下面将详细对比这三者的主要差异:
3.1 语言与开发背景
- Kafka :采用Scala语言开发,最初由LinkedIn开发并开源,后来成为Apache软件基金会的一部分。Kafka主要用于处理活跃的流式数据,特别适用于高吞吐量的实时数据流处理和流式处理场景。
- RabbitMQ :由Erlang语言开发,Erlang是一种高并发的编程语言,使得RabbitMQ非常适合用于实时的、对可靠性要求较高的消息传递上。
- RocketMQ :采用Java语言开发,由阿里巴巴开源,是阿里巴巴分布式消息中间件的一个核心组件。RocketMQ具有较高的吞吐量和稳定性,适用于大规模数据处理和高吞吐量的场景。
3.2 吞吐量与性能
- Kafka:具有极高的吞吐量和低延迟,单机可支持数百万级别消息/秒的处理能力。这得益于其Zero Copy机制、磁盘顺序读写、批量处理机制、分区机制等优化措施。
- RabbitMQ:与Kafka和RocketMQ相比,RabbitMQ的吞吐量相对较低。它更适用于处理不是那么紧急或者不那么高速的消息。
- RocketMQ:虽然RocketMQ的吞吐量也非常高,但与Kafka相比仍稍逊一筹。RocketMQ支持简单的水平扩展,可以通过添加新的broker节点来提高容量和可用性。
3.3 可靠性与容错性
- Kafka:采用分布式架构,支持副本机制,可以确保消息在发送时不会丢失,并且可以通过多个副本来保证消息的可靠性。Kafka支持同步和异步两种消息复制方式,但异步复制可能导致数据丢失。
- RabbitMQ:具有非常高的可靠性,支持多种消息确认机制,如生产者确认、消费者确认等,可以确保消息不会丢失。RabbitMQ还支持事务,但事务的使用可能会形成阻塞。
- RocketMQ:同样采用分布式架构,支持同步刷盘和异步刷盘,以及同步Replication和异步Replication。RocketMQ的同步刷盘在单机可靠性上比Kafka更高,不会因为操作系统Crash导致数据丢失。
3.4 使用场景
- Kafka:广泛应用于日志收集、实时数据处理、消息系统以及流处理等场景。Kafka的高吞吐量和低延迟特性使其成为处理大规模数据流的理想选择。
- RabbitMQ:适用于各种异步任务队列,如邮件发送、短信发送、图片和视频转码等。RabbitMQ还支持高级的消息模型,如RPC、请求-响应和消费者确认等,适用于企业级应用。
- RocketMQ:适用于大规模消息传输和处理场景,如电商平台订单、库存消息等。RocketMQ还支持分布式事务消息和顺序消息等高级功能,适用于对消息顺序和事务性有较高要求的场景。
3.5 其他特性
- Kafka:支持多分区、多生产者、多消费者,基于订阅模式,支持发布-订阅和点对点通信。Kafka还支持消息持久化,可支持数天甚至数月的数据存储。
- RabbitMQ:支持多种消息协议,包括AMQP、STOMP、MQTT等,可以满足不同的应用需求。RabbitMQ的配置和管理相对简单,易于上手。
- RocketMQ:提供了易于使用的API,支持多种编程语言。RocketMQ还支持消息查询和回溯功能,有助于定位消息丢失问题和重新消费历史消息。
综上所述,Kafka、RabbitMQ和RocketMQ在语言、吞吐量、可靠性、使用场景等方面各有千秋。选择哪个消息队列系统取决于具体的应用场景和需求。
参考 kafka和rabbitmq对比(超详细,从实战维度比较)、RabbitMQ和kafka的区别(详细版)、何时使用Kafka而不是RabbitMQ