kafka、activemq、rabbitmq、rocketmq的优缺点和使用场景
1. 消息队列的使用场景
消息队列的使用场景有很多,最核心的有三个:解耦、异步、削峰
解耦:一个系统或者一个模块,调用了多个系统或者模块,相互之间的调用很复杂,维护起来很麻烦。此时可以考虑使用消息队列来实现多个系统之间的解耦
异步:系统A接受一个请求,需要在自己本地写库,还需要在系统BCD三个系统写库,同步操作比较费时。
削峰:高峰时段系统接收到的请求缓存到消息队列,供系统根据负载慢慢消化
2. 消息队列的缺点
- 系统可用性降低:MQ宕机之后整套系统均不能正常使用
- 系统复杂性提高:存在消息重复消费、消息丢失、消息传递顺序不能保证的问题
- 一致性问题:多个系统消费存在部分成功部分失败的问题,数据不一致了
3. kafka、activemq、rabbitmq、rocketmq对比
特性 | ActiveMQ | RabbitMQ | RocketMQ | kafka |
---|---|---|---|---|
单机吞吐量 | 万级 | 万级 | 10万级,RocketMQ也是可以支撑高吞吐的一种MQ | 10万级别,吞吐量高。一般配合大数据类的系统来进行实时数据计算、日志采集等场景 |
topic数量对吞吐量的影响 | topic可以达到几百,几千个的级别,吞吐量会有较小幅度的下降,这是RocketMQ的一大优势,在同等机器下,可以支撑大量的topic | topic从几十个到几百个的时候,吞吐量会大幅度下降所以在同等机器下,kafka尽量保证topic数量不要过多。如果要支撑大规模topic,需要增加更多的机器资源 | ||
时效性 | ms级 | 微秒级,这是rabbitmq的一大特点,延迟是最低的 | ms级 | ms级以内 |
可用性 | 高,基于主从架构实现高可用性 | 高,基于主从架构实现高可用性 | 非常高,分布式架构 | 非常高,kafka是分布式的,一个数据多个副本,少数机器宕机,不会丢失数据,不会导致不可用 |
消息可靠性 | 有较低的概率丢失数据 | 经过参数优化配置,可以做到0丢失 | 经过参数优化配置,可以做到0丢失 | |
功能支持 | MQ领域的功能极其完备 | 基于erlang开发,所以并发能力很强,性能极其好,延时很低 | MQ功能较为完善,还是分布式的,扩展性好 | 功能较为简单,主要支持简单的MQ功能,在大数据领域的实时计算以及日志采集被大规模使用,是事实上的标准 |
优劣势总结 | 非常成熟,功能强大,在业内大量的公司以及项目中都有应用;偶尔会有较低概率丢失消息,而且现在社区以及国内应用都越来越少,官方社区现在对ActiveMQ 5.x维护越来越少,几个月才发布一个版本,而且确实主要是基于解耦和异步来用的,较少在大规模吞吐的场景中使用 | erlang语言开发,性能极其好,延时很低;吞吐量到万级,MQ功能比较完备;而且开源提供的管理界面非常棒,用起来很好用;社区相对比较活跃,几乎每个月都发布几个版本分;在国内一些互联网公司近几年用rabbitmq也比较多一些;但是问题也是显而易见的,RabbitMQ确实吞吐量会低一些,这是因为他做的实现机制比较重。erlang开发,基本只能依赖于开源社区的快速维护和修复bug。而且rabbitmq集群动态扩展会很麻烦。其实主要是erlang语言本身带来的问题。很难读源码,很难定制和掌控。 | 接口简单易用,而且毕竟在阿里大规模应用过,有阿里品牌保障;处理消息上百亿之多,可以做到大规模吞吐,性能也非常好,分布式扩展也很方便,社区维护还可以,可靠性和可用性都是ok的,还可以支撑大规模的topic数量,支持复杂MQ业务场景;而且一个很大的优势在于,阿里出品都是java系的,我们可以自己阅读源码,定制自己公司的MQ,可以掌控;社区活跃度相对较为一般,不过也还可以,文档相对来说简单一些,然后接口这块不是按照标准JMS规范走的有些系统要迁移需要修改大量代码;还有就是阿里出台的技术,你得做好这个技术万一被抛弃,社区黄掉的风险,那如果你们公司有技术实力我觉得用RocketMQ挺好的 | kafka的特点其实很明显,就是仅仅提供较少的核心功能,但是提供超高的吞吐量,ms级的延迟,极高的可用性以及可靠性,而且分布式可以任意扩展;同时kafka最好是支撑较少的topic数量即可,保证其超高吞吐量;而且kafka唯一的一点劣势是有可能消息重复消费,那么对数据准确性会造成极其轻微的影响,在大数据领域中以及日志采集中,这点轻微影响可以忽略;这个特性天然适合大数据实时计算以及日志收集 |
- 如何保证消息队列的高可用?
- RabbitMQ基于主从的高可用,分为单机模式、普通集群模式、镜像集群模式三种
普通集群模式:多台服务器部署RabbitMQ,一个queue只会保存在一个节点上,其他节点只会同步该queue的元数据,当请求从其他节点获取该queue的数据时,该节点会再次去存储该queue的节点上拉取所需数据。这样就导致使用时要么固定使用其中一个节点,要么随机节点再需要的时候拉取数据。如果存放数据的节点宕机了,其他节点就无法拉取数据,如果开启了消息持久化让RabbitMQ落地存储消息就不一定会丢失消息,得等这个实例恢复后才能继续从这个queue拉取数据。
镜像集群模式(高可用模式):创建的queue会同步到所有实例上来实现高可用。这样会带来同步数据的开销和扩展性降低(扩展机器会导致新增的机器同步queue增加更多同步数据的开销);配置方式可通过控制台配置。 - Kafka的高可用:分布式消息队列
Kafka由多个broker组成,每个broker是一个节点,创建的一个topic划分为多个partition,每个partition可放在不同的broker上,每个partition只存放一部分数据。
RocketMQ的实现原理
RocketMQ是一个分布式的消息中间件,它具有高吞吐量、高可靠性、低延迟、可扩展性等特点,它可以支持多种消息模式,如发布/订阅、请求/响应和流式处理等。RocketMQ的实现原理可以从以下几个方面来介绍:
- RocketMQ的架构
RocketMQ的架构由四个部分组成:Name Server、Broker、Producer和Consumer。它们的作用和关系如下所示:
- Name Server:负责管理Broker的注册和发现,以及提供路由信息给Producer和Consumer。Name Server是无状态的,可以部署多个实例,实现高可用性。
- Broker:负责存储和转发消息,以及处理消费者的拉取请求。Broker可以分为主从两种角色,主Broker负责读写消息,从Broker负责同步主Broker的消息,实现数据备份。Broker可以分为多个集群,每个集群可以包含多个主从Broker对,实现负载均衡和容灾。
- Producer:负责生产和发送消息到Broker。Producer可以分为多个组,每个组可以包含多个Producer实例,实现高并发和高可用性。
- Consumer:负责消费Broker中的消息。Consumer可以分为两种模式:推模式(Push Mode)和拉模式(Pull Mode)。推模式是指Broker主动将消息推送给Consumer,适合于实时性要求较高的场景;拉模式是指Consumer主动向Broker拉取消息,适合于实时性要求较低的场景。Consumer也可以分为多个组,每个组可以包含多个Consumer实例,实现负载均衡和容灾。
- RocketMQ的存储机制
RocketMQ的存储机制是基于文件系统的,它将消息以日志文件(Commit Log)的形式存储在磁盘上,并通过索引文件(Index File)来提高查询效率。RocketMQ的存储机制具有以下几个特点:
- 顺序写入:RocketMQ将所有类型的消息都顺序地写入到同一个日志文件中,避免了随机写入带来的磁盘寻道开销,提高了写入性能。
- 映射内存:RocketMQ利用操作系统的内存映射(Memory Mapping)机制,将日志文件映射到内存中,加快了读写速度,并减少了内存占用。
- 异步刷盘:RocketMQ支持两种刷盘方式:同步刷盘(Synchronous Flush)和异步刷盘(Asynchronous Flush)。同步刷盘是指每次写入消息后都要将缓冲区中的数据刷入磁盘,保证数据不丢失,但是性能较低;异步刷盘是指每次写入消息后不立即刷入磁盘,而是定期或按条件刷入磁盘,提高了性能,但是有一定的数据丢失风险。
- 消息过滤:RocketMQ支持两种消息过滤方式:标签过滤(Tag Filter)和SQL92过滤(SQL92 Filter)。标签过滤是指根据消息的标签(Tag)来进行过滤,适合于简单的过滤条件;SQL92过滤是指根据消息的属性(Property)来进行过滤,适合于复杂的过滤条件。
- RocketMQ的传输协议
RocketMQ的传输协议是基于TCP/IP协议的,它定义了一套自定义的消息格式和命令,用于在Name Server、Broker、Producer和Consumer之间进行通信。RocketMQ的传输协议具有以下几个特点:
- 可扩展性:RocketMQ的传输协议采用了类似HTTP的请求/响应模式,每个请求或响应都包含一个头部(Header)和一个正文(Body)。头部中包含了命令码(Code)、语言(Language)、版本(Version)等信息,正文中包含了具体的业务数据。RocketMQ的传输协议可以根据不同的命令码来扩展不同的功能,如发送消息、拉取消息、创建主题等。
- 可靠性:RocketMQ的传输协议采用了类似TCP的可靠传输机制,它通过序列号(Sequence Number)、确认号(Acknowledge Number)、重传机制等来保证数据的完整性和有序性。
- 高效性:RocketMQ的传输协议采用了类似NIO的异步通信机制,它通过多路复用(Multiplexing)、非阻塞(Non-blocking)、事件驱动(Event-driven)等技术来提高网络通信的效率和并发性。