消息队列
概述
实现系统间通信的方法
- 基于远程过程调用,RPC
- 基于消息队列
各种消息队列的使用场景
- 解耦
- 异步处理业务
- 消息队列关注的是通知, 而不是处理
- 流量消峰
- 日志收集
- 事务最终一致性
功能特点
- 消息的发送
- 消息的接收
- 消息的暂存
- 其他
- 消息堆积
- 消息持久化
- 可靠性传递
- 消息重复
- 严格有序
- 集群高可用
特征
- 生产者消费者独立
- 不能让生产者要求知道那个消费者消费
- 持久性
- 高吞吐
- 强序事件流的可重放序列
- 容错性
消息队列的模式
- 生产者消费者模式(Producer-Consumer)
- 发布订阅模式(Publish-Subscribe)
- 请求回应模型(Request-Reply)
rabbitMQ
- 具有应答机制
- 特点
- 由Erlang开发的
- 基于AMOP协议
- AMQP的主要特征是面向消息、队列、路由(包括点对点和发布/订阅)、可靠性、安全
- 对数据一致性、稳定性和可靠性要求很高的场景,对性能和吞吐量的要求还在其次
- 拥有灵活的路由
- 支持集群高可用
- 在一个队列里面,rabbitmq的消息是严格顺序的,按照先进先出
- RabbitMQ的消息应当尽可能的小,并且只用来处理实时且要高可靠性的消息。
activeMQ
老的消息队列
单机吞吐量:万级
topic数量都吞吐量的影响:
时效性:ms级
可用性:高,基于主从架构实现高可用性
消息可靠性:有较低的概率丢失数据
功能支持:MQ领域的功能极其完备
官方社区现在对ActiveMQ 5.x维护越来越少,较少在大规模吞吐的场景中使用。
kafka
!没有应答机制
特点
- 为发布和订阅都提供了搞吞吐设计
- 消息持久化
- 消息消费为pull模式
- 消息被处理状态保存在consumer中
- consumer自己保存offerset
- broker无状态
- 支持online和offline
- 在同一个partition中消息是有序的
- 生产者put到Kafka中数据会分布在不同的partition中,所有总体是无序的
- 吞吐量更大
- Kafka的业务应用场景主要定位于日志传输;对于复杂业务支持不够
- 不支持AMQP事务处理
rocketMQ
它对消息的可靠传输及事务性做了优化
吞吐量大
RocketMQ适合业务处理。
特点
- 具有灵活的拓展性
- NameServeer
- Broker
- Producer
- Consumer
- 海量消息堆积能力
- 零拷贝
- CPU不执行拷贝数据从一个存储区域到另一个存储区域的任务
- 这通常用于通过网络传输一个文件时以减少CPU周期和内存带宽
- 我们看到“零拷贝”是指计算机操作的过程中,CPU不需要为数据在内存之间的拷贝消耗资源。而它通常是指计算机在网络上发送文件时,不需要将文件内容拷贝到用户空间(User Space)而直接在内核空间(Kernel Space)中传输到网络的方式。
- 支持数据顺序
- 支持多种过滤方法
- 支持事务
- 支持回溯消费
优势
- Kafka的业务应用场景主要定位于日志传输;对于复杂业务支持不够
- 阿里很多业务场景对数据可靠性、数据实时性、消息队列的个数等方面的要求很高
- kafka针对海量数据,但是对数据的正确度要求不是十分严格
- 阿里巴巴中用于交易相关的事情较多,对数据的正确性要求极高,Kafka不合适
kafka vs rocketMQ
-前者吞吐量大, 后者可靠性更高
调度差异
- kafka在具备选举功能,在Kafka里面,Master/Slave的选举,有2步
- 第1步,先通过ZK在所有机器中,选举出一个KafkaController
- 第2步,再由这个Controller,决定每个partition的Master是谁,Slave是谁
- 因为有了选举功能,所以kafka某个partition的master挂了,该partition对应的某个slave会升级为主对外提供服务
- rocketMQ不具备选举,Master/Slave的角色也是固定的
- 当一个Master挂了之后,你可以写到其他Master上,但不能让一个Slave切换成Master
- rocketMq的所有broker节点的角色都是一样,上面分配的topic和对应的queue的数量也是一样的,Mq只能保证当一个broker挂了,把原本写到这个broker的请求迁移到其他broker上面,而并不是这个broker对应的slave升级为主
吞吐量对比
- kafka在消息存储过程中会根据topic和partition的数量创建物理文件,也就是说我们创建一个topic并指定了3个partition,那么就会有3个物理文件目录,也就说说partition的数量和对应的物理文件是一一对应的
- rocketMq在消息存储方式就一个物流问题,也就说传说中的commitLog,rocketMq的queue的数量其实是在consumeQueue里面体现的,在真正存储消息的commitLog其实就只有一个物理文件。
- kafka的多文件并发写入 VS rocketMq的单文件写入,性能差异kafka完胜可想而知
- kafka的大量文件存储会导致一个问题,也就说在partition特别多的时候,磁盘的访问会发生很大的瓶颈,毕竟单个文件看着是append操作,但是多个文件之间必然会导致磁盘的寻道。
写入与读取对比
消息投递实时性
- 在服务端处理同步发送的性能上,Kafka>RocketMQ>RabbitMQ。
- Kafka使用短轮询方式,实时性取决于轮询间隔时间,0.8以后版本支持长轮询
- 均支持pull长轮询,RocketMQ消息实时性更好
数据可靠性
- Rocket可靠性更强
- 同步刷盘不会因为系统问题而导致消息丢失
- RocketMQ支持异步实时刷盘,同步刷盘,同步复制,异步复制
- 卡夫卡使用异步刷盘方式,异步复制/同步复制
支持的队列数
- Kafka单机超过64个队列/分区,消息发送性能降低严重;
- RocketMQ 单机支持最高5万个队列,性能稳定
- rocketMq支持更多的topic, 更适合业务场景, 原因在于吞吐量那一节, 此队列并不追求吞吐量
- 长远来看,RocketMQ 胜出,这也是适合业务处理的原因之一
消息顺序性
- Kafka 某些配置下,支持消息顺序,但是一台Broker宕机后,就会产生消息乱序;
- RocketMQ支持严格的消息顺序,在顺序消息场景下,一台Broker宕机后发送消息会失败,但是不会乱序;
- MySQL的二进制日志分发等需要严格的消息顺序
失败重试
- Kafka消费失败不支持重试
- RocketMQ消费失败支持定时重试,每次重试间隔时间顺延。
- 更适合业务场景
定时/延时消息
- Kafka不支持定时消息;
- RocketMQ支持定时消息
分布式事务消息
- Kafka不支持分布式事务消息;
- 阿里云ONS支持分布式定时消息,未来开源版本的RocketMQ也有计划支持分布式事务消息
消息查询机制
- Kafka不支持消息查询
- RocketMQ支持根据Message Id查询消息,也支持根据消息内容查询消息
消息回溯
- Kafka理论上可以按照Offset来回溯消息
- RocketMQ支持按照时间来回溯消息,精度毫秒,例如从一天之前的某时某分某秒开始重新消费消息