一、kafka和rabbitmq全面对比分析1.1 简介kafka是apache开源的消息队列顶级项目之一在大数据场景下使用较多由linkedin开源目前社区活跃全球较多组织开始使用kafka来进行数据交换。kafka采用mq结构broker有part分区的概念RabbitMQ是流行的开源消息队列系统用erlang语言开发。RabbitMQ是AMQPAdvanced Message Queuing Protocol高级消息队列协议的标准实现。RabbitMQ的broker由Exchange、Binding、queue组成。1.2 kafka和rabbitmq全面对比分析对比项kafkarabbitmq开发语言scala,Javaerlang是否支持多租户2.x.x支持多租户支持多租户是否支持topic优先级不支持支持是否支持消息全局有序不支持支持是否支持消息分区有序支持支持是否内置监控无内置监控内置监控是否支持多个生产者一个topic支持多个生产者是否支持多个消费者一个topic支持多个消费者(一个消费者可消费多个分区一个分区可被多个消费组消费但同一消费组内仅能有一个消费者同时消费1个分区)是否支持一个分区多个消费者不支持不支持是否支持JMX支持不支持(非java语言编写)是否支持加密支持支持消息队列协议支持仅支持自定义协议支持AMQP、MQTT、STOMP协议客户端语言支持支持多语言客户端支持多语言客户端是否支持消息追踪不支持消息追踪支持消息追踪是否支持消费者推模式不支持消费者推模式支持消费者推模式是否支持消费者拉模式支持消费者拉模式支持消费者拉模式是否支持广播消息支持广播消息支持广播消息是否支持消息回溯支持消息回溯因为消息持久化消息被消费后会记录offset和timstamp不支持消息确认被消费后会被删除是否支持消息数据持久化支持消息数据持久支持消息数据持久是否支持消息堆积支持消息堆积并批量持久化到磁盘支持阈值内的消息对接无法支持较大的消息堆积是否支持流量控制支持控制用户和客户端流量支持生产者的流量控制是否支持事务性消息支持不支持元数据管理通过zookeeper进行管理支持消息数据持久默认服务端口90925672默认监控端口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 设计目标和适用场景RabbitMQRabbitMQ是一个传统的消息队列系统采用了基于消息队列的发布-订阅模型设计目标RabbitMQ的设计目标是确保消息的可靠传递并提供多种消息传递协议的支持应用场景通常用于实时的、对可靠性要求较高的消息传递上中小项目项目消息量小、吞吐量不高、对延时敏感遗留应用如需要与旧系统或第三方系统进行集成或通信复杂路由如需要根据不同的规则或条件来分发或过滤消息延迟敏感对于消费者处理消息的及时性有非常高的要求KafkaKafka是一个分布式事件流平台采用了发布-订阅日志模型设计目标Kafka的设计目标是提供高吞吐量和持久化存储支持事件溯源、数据湖等长期存储需求应用场景主要用于处理活跃的流式数据特别适用于大数据量的数据处理场景。跟踪高吞吐量的活动如网站点击、应用日志、传感器数据等事件溯源Kafka 保存着所有历史消息可以用于事件回溯和审计流式处理如实时分析、实时推荐、实时报警等日志聚合如收集不同来源的日志并统一存储和分析2.1.2 架构模型方面producerbrokerconsumerRabbitMQ以broker为中心有消息的确认机制这里的确认机制指的是客户端消费消息的时候broker与consumer交互方式rabbitmq采用push的方式kafka以consumer为中心无消息的确认机制这里的确认机制指的是客户端消费消息的时候broker与consumer交互方式rabbitmq采用pull的方式kafka和rabbitMQ都有发送到Broker的确认机制。2.1.3 吞吐量和性能RabbitMQ支持消息的可靠传递支持事务不支持批量操作基于存储的可靠性的要求存储可以采用内存或硬盘吞吐量小在处理大量消息时可能会受限于单一队列的性能瓶颈。如果需要持久化会采用实时存储kafka内部采用消息的批量处理数据的存储和获取是本地磁盘顺序批量操作消息处理的效率高吞吐量高,这得益于其分布式架构、分区机制以及批量处理等技术。定时持久化存储非实时持久化储存2.1.4 消息存储和持久化RabbitMQRabbitMQ通常保留消息一段时间然后将其删除。虽然它也支持消息的持久化但主要是为了确保消息在传递过程中的可靠性而不是为了长期存储。KafkaKafka以持久化日志的方式存储消息允许消息长时间保留。这种设计使得Kafka非常适合用于需要长期存储和回溯消息的场景。2.1.5 消息传递保证RabbitMQRabbitMQ提供不同级别的消息传递保证包括至少一次传递、至多一次传递和确切一次传递。这些保证机制可以根据应用的需求进行配置。KafkaKafka提供了强大的消息保证确保消息的持久性、顺序性和可靠性传递。Kafka的分区和副本机制使得即使在节点故障的情况下也能保证消息的不丢失。2.1.6 集群负载均衡方面RabbitMQ本身不支持负载均衡需要loadbalancer的支持。即指定存到哪个broker就是哪个brokerkafka采用zookeeper对集群中的broker、consumer进行管理可以注册topic到zookeeper上通过zookeeper的协调机制producer保存对应的topic的broker信息可以随机或者轮询发送到broker上producer可以基于语义指定分片消息发送到broker的某个分片上。即如果不指定分片就会默认存到master的分片上然后再同步到其他的分片2.1.7 生态系统和社区支持RabbitMQRabbitMQ有一个成熟的生态系统包括多种客户端库和插件适用于各种编程语言和应用场景。它拥有广泛的用户群体和活跃的社区支持。KafkaKafka同样拥有一个庞大的生态系统特别适用于大规模数据处理和日志管理。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 扩展性和分布式特性RabbitMQRabbitMQ可以通过集群来水平扩展但在某些情况下水平扩展可能不够灵活。它支持多种交换机类型和绑定选项使得消息可以在多个路由路径中进行传递。KafkaKafka是天生分布式的易于水平扩展。它可以在不断增加的负载下轻松添加新的节点并且支持多个生产者和消费者同时工作。Kafka的分区机制使得消息可以均匀分布在多个节点上从而提高了系统的整体性能。2.2.5 集群了解即可无需掌握RabbitMQ队列同步发起方Rabbit使用的镜像集群非默认的主从集群镜像队列同步时由主队列向镜像队列发起副本同步限制副本队列可以落后主队列很多副本同步对性能的影响Rabbit使用的镜像集群非默认的主从集群新节点加入时如果ha-sync-modemanual则不会手动同步镜像到新节点。如果ha-sync-modeautomatic时会自动同步到新节点中。在同步新节点时主节点不会再接收生产者的消息也不会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在语言、吞吐量、可靠性、使用场景等方面各有千秋。选择哪个消息队列系统取决于具体的应用场景和需求。