消息队列选型
消息队列(Message Queue),简称MQ,本质是一个队列,用于存放数据(message),先入先出(FIFO)。主要用于系统解耦、消息缓存。
目前市面上消息队列的实现有很多种,下面调研了kafka/rabbitMQ/rocketMQ,这三种应用都非常广泛,期望从中选出最合适我们的。
简介
- Kafka是LinkedIn开源的分布式发布-订阅消息系统,目前归属于Apache定级项目。Kafka主要特点是基于Pull的模式来处理消息消费,追求高吞吐量,一开始的目的就是用于日志收集和传输。0.8版本开始支持复制,不支持事务,对消息的重复、丢失、错误没有严格要求,适合产生大量数据的互联网服务的数据收集业务。
- RabbitMQ是使用Erlang语言开发的开源消息队列系统,基于AMQP协议来实现。AMQP的主要特征是面向消息、队列、路由(包括点对点和发布/订阅)、可靠性、安全。AMQP协议更多用在企业系统内,对数据一致性、稳定性和可靠性要求很高的场景,对性能和吞吐量的要求还在其次。
- RocketMQ是阿里开源的消息中间件,它是纯Java开发,具有高吞吐量、高可用性、适合大规模分布式系统应用的特点。RocketMQ思路起源于Kafka,但并不是Kafka的一个Copy,它对消息的可靠传输及事务性做了优化,目前在阿里集团被广泛应用于交易、充值、流计算、消息推送、日志流式处理、binglog分发等场景。
原理
- kafka:每台服务器为一个broker,每种消息为一个topic,每个topic分为1或多个partition。每个partition为一个物理文件存储,且是排序存储的。消息存储时,会复制到其他broker上,一台broker挂了后保证消息不丢失。
- rocketMQ:与kafka类似,每台服务器为一个broker,每种消息为一个topic,每个topic分为1或多个queue。每个broker可以配置主从,来实现高可用。主从间可采用同步或异步策略来复制消息。
- rabbitMQ:每台服务器为一个broker,发送方发送消息时每类消息有一个RoutingKey,接受方监听一个消息存储的queue,中间有个exchange将RoutingKey按照路由规则放到指定的queue中。
特性对比
特性 | kafka | rabbitMQ | rocketMQ |
可用性 | 很高 | 高 | 高 |
持久化 | 支持 | 支持 | 支持 |
顺序消费 | 支持 | 支持 | 支持 |
事务 | 不支持 | 支持 | 支持 |
单机吞吐量 | 十万级 | 万级 | 十万级 |
文档完备性 | 高 | 高 | 高 |
多语言支持 | 支持 | 支持 | 支持 |
消息通知方式 | pull | pull & push | pull |
高可用性
kafka:分布式部署,数据会被负复制到其他节点,一个节点挂了后,会自动切换到其他节点。
rocketMQ:主从结构,数据会负责到从节点,主节点挂了会从从节点选举一个主节点出来
rabbitMQ:有普通模式和镜像模式,镜像模式支持高可用,此模式下,队列的数据复制一份到所有节点上。主节点失效时,mirror queue内部有一套选举算法,会选出一个master,和若干个slaver。
顺序消费消息
kafka:支持。但一个节点失效后,顺序会被打乱,但不是丢失。
rocketMQ:支持。一个节点失效后,发送消息会失败,此节点恢复后,能发送成功且顺序不变。
rabbitMQ:支持。
分布式事务
kafka:不支持
rocketMQ:支持。用两段提交来实现,第一阶段发送消息时,拿到消息offset,第二阶段通过 offset来修改消息状态。
rabbitMQ:支持。可用两段提交或者confirm机制来实现。confirm机制:发送方发送消息,broker立即返回ok,broker异步处理消息,将处理结果通知发送方。
结论
没有哪种有明显的优势,kafka在于分布式架构,rabbitMQ基于AMQP协议来实现,rocketMQ思路来源于kafka,改成了主从结构,在事务性可靠性方面做了优化。宽泛来说,电商、金融等对事务性要求很高的,可以考虑rabbitMQ和rocketMQ,对性能要求高的可考虑kafka。
个人比较倾向于kafka,它的加分项:分布式架构的高可用性,便捷的扩展性。
【本文由“科学视角”发布,2017年5月9日】