前言

开源社区有好多优秀的队列中间件,比如RabbitMQ和Kafka,每个队列都貌似有其特性,在进行工程选择时,往往眼花缭乱,不知所措。

对于RabbitMQ和Kafka,到底应该选哪个?

RabbitMQ架构

RabbitMQ是一个分布式系统,这里面有几个抽象概念。

  • broker:每个节点运行的服务程序,功能为维护该节点的队列的增删以及转发队列操作请求。

  • master queue:每个队列都分为一个主队列和若干个镜像队列。

  • mirror queue:镜像队列,作为master queue的备份。在master queue所在节点挂掉之后,系统把mirror queue提升为master queue,负责处理客户端队列操作请求。注意,mirror queue只做镜像,设计目的不是为了承担客户端读写压力。

如上图所示,集群中有两个节点,每个节点上有一个broker,每个broker负责本机上队列的维护,并且borker之间可以互相通信。集群中有两个队列A和B,每个队列都分为master queue和mirror queue(备份)。

队列消费

如上图有两个consumer消费队列A,这两个consumer连在了集群的不同机器上。
RabbitMQ集群中的任何一个节点都拥有集群上所有队列的元信息,所以连接到集群中的任何一个节点都可以,主要区别在于有的consumer连在master queue所在节点,有的连在非master queue节点上。
因为mirror queue要和master queue保持一致,故需要同步机制,正因为一致性的限制,导致所有的读写操作都必须都操作在master queue上(想想,为啥读也要从master queue中读?和数据库读写分离是不一样的。),然后由master节点同步操作到mirror queue所在的节点。即使consumer连接到了非master queue节点,该consumer的操作也会被路由到master queue所在的节点上,这样才能进行消费。

队列生产

原理和消费一样,如果连接到非 master queue 节点,则路由过去。
关注微信公众号:Java技术栈,在后台回复:架构,可以获取我整理的 N 篇最新架构教程,都是干货。
所以,到这里小伙伴们就可以看到 RabbitMQ的不足:由于master queue单节点,导致性能瓶颈,吞吐量受限。虽然为了提高性能,内部使用了Erlang这个语言实现,但是终究摆脱不了架构设计上的致命缺陷。

Kafka

说实话,Kafka我觉得就是看到了RabbitMQ这个缺陷才设计出的一个改进版,改进的点就是:把一个队列的单一master变成多个master,即一台机器扛不住qps,那么我就用多台机器扛qps,把一个队列的流量均匀分散在多台机器上不就可以了么?注意,多个master之间的数据没有交集,即一条消息要么发送到这个master queue,要么发送到另外一个master queue。

这里面的每个master queue 在Kafka中叫做Partition,即一个分片。一个队列有多个主分片,每个主分片又有若干副分片做备份,同步机制类似于RabbitMQ。

如上图,我们省略了不同的queue,假设集群上只有一个queue(Kafka中叫Topic)。每个生产者随机把消息发送到主分片上,之后主分片再同步给副分片。

队列读取的时候虚拟出一个Group的概念,一个Topic内部的消息,只会路由到同Group内的一个consumer上,同一个Group中的consumer消费的消息是不一样的;Group之间共享一个Topic,看起来就是一个队列的多个拷贝。

所以,为了达到多个Group共享一个Topic数据,Kafka并不会像RabbitMQ那样消息消费完毕立马删除,而是必须在后台配置保存日期,即只保存最近一段时间的消息,超过这个时间的消息就会从磁盘删除,这样就保证了在一个时间段内,Topic数据对所有Group可见(这个特性使得Kafka非常适合做一个公司的数据总线)。队列读同样是读主分片,并且为了优化性能,消费者与主分片有一一的对应关系,如果消费者数目大于分片数,则存在某些消费者得不到消息。

由此可见,Kafka绝对是为了高吞吐量设计的,比如设置分片数为100,那么就有100台机器去扛一个Topic的流量,当然比RabbitMQ的单机性能好。

总结

本文只做了Kafka和RabbitMQ的对比,但是开源队列岂止这两个,ZeroMQ,RocketMQ,JMQ等等,时间有限也就没有细看,故不在本文比较范围之内。

所以,别再被这些五花八门的队列迷惑了,从架构上找出关键差别,并结合自己的实际需求(比如本文就只单单从吞吐量一个需求来考察)轻轻松松搞定选型。最后总结如下:

  • 吞吐量较低:Kafka和RabbitMQ都可以。

  • 吞吐量高:Kafka。

本文内容参考自RabbitMQ和KafKa官方文档,所以真要搞懂一个中间件的原理最好去看官方文档,文档里面有详细的设计方案,我们可以自己进行设计方案的对比,从而找出符合自己实际情况的中间件。

作者:haolujun

https://www.cnblogs.com/haolujun/p/9632835.html

- END -
推荐阅读:

关注Java技术栈公众号在后台回复:Java,可获取一份栈长整理的最新 Java 技术干货。

点击「阅读原文」和栈长学更多~

头大!RabbitMQ 和 Kafka 到底怎么选?的更多相关文章

  1. RabbitMQ和Kafka到底怎么选(二)?

    前言 前一篇文章<RabbitMQ和Kafka到底怎么选?>,我们在吞吐量方面比较了Kafka和RabbitMQ,知道了Kafka的吞吐量要高于RabbitMQ.本文从可靠性方面继续探讨两 ...

  2. RabbitMQ和Kafka到底怎么选?

    前言 开源社区有好多优秀的队列中间件,比如RabbitMQ和Kafka,每个队列都貌似有其特性,在进行工程选择时,往往眼花缭乱,不知所措.对于RabbitMQ和Kafka,到底应该选哪个? Rabbi ...

  3. RabbitMQ 和 Kafka

    ============================RabbitMQ 术语============================RabbitMQ 有很多术语和Kafka不一样, 理解这些术语十分 ...

  4. rabbitmq和kafka怎么选?【转】

    MQ框架非常之多,今天简单说一下有代表性的两个MQ(rabbitmq和kafka).经常会有人问rabbitmq和kafka到底哪个好呢?其实没有好与不好之分,只有哪个更合适,首先要根据自己项目的业务 ...

  5. MQ选型对比ActiveMQ,RabbitMQ,RocketMQ,Kafka 消息队列框架选哪个?

    最近研究消息队列,发现好几个框架,搜罗一下进行对比,说一下选型说明: 1)中小型软件公司,建议选RabbitMQ.一方面,erlang语言天生具备高并发的特性,而且他的管理界面用起来十分方便.不考虑r ...

  6. RabbitMQ和Kafka对比

    # 前言 开源社区有好多优秀的队列中间件,比如RabbitMQ和Kafka,每个队列都貌似有其特性,在进行工程选择时,往往眼花缭乱,不知所措.对于RabbitMQ和Kafka,到底应该选哪个? # R ...

  7. 关于ActiveMQ、RocketMQ、RabbitMQ、Kafka一些总结和区别

    这是一篇分享文 转自:http://www.cnblogs.com/williamjie/p/9481780.html  尊重原作,谢谢 消息队列 为什么写这篇文章? 博主有两位朋友分别是小A和小B: ...

  8. 消息队列 ActiveMQ 、RocketMQ 、RabbitMQ 和 Kafka 如何选择?

    「 预计阅读 6 分钟 」 旁白:这是一篇拖更了N久的文章...0.0(看不见我~) 往期回顾 前端框架 jQuery 和 Vue 如何选择? 安全框架 Shiro 和 Spring Security ...

  9. 8.关于ActiveMQ、RocketMQ、RabbitMQ、Kafka一些总结和区别

    这是一篇分享文 转自:http://www.cnblogs.com/williamjie/p/9481780.html  尊重原作,谢谢 消息队列 为什么写这篇文章? 博主有两位朋友分别是小A和小B: ...

随机推荐

  1. 从收发消息能力来理解TCP建立连接时的三次握手

    TCP是一个全双工协议,意味着在Client和Server都可以接收和发送数据. 所以,从另一个角度理解建立连接的目的就是要确保双方都要知道对端的收发消息的能力是正常的

  2. 文件操作:fopen()

    r 打开只读文件,该文件必须存在. r+ 打开可读写的文件,该文件必须存在.   rb+ 读写打开一个二进制文件,只允许读写数据. rt+ 读写打开一个文本文件,允许读和写.    w 打开只写文件, ...

  3. MySQL的字符集操作命令总结

    这篇文章主要介绍了MySQL的字符集操作命令总结,包括各种查看数据库.数据表等查询命令,需要的朋友可以参考下   以下均在mysql 5.5命令行中运行通过: 查看MySQL支持的字符集: 代码如下: ...

  4. NS3安装

    1.添加源sudo vim /etc/apt/sources.list deb http://archive.ubuntu.com/ubuntu/ trusty main universe restr ...

  5. 5.聚类算法k-means

    聚类与分类的区别在于,是在没有给定划分类别的情况下,更具数据相似度进行样本分组的一种办法,是一种非监督的学习算法,聚类的输入时一组未被标记的样本,聚类更具数据自身的距离或者相似度将其划分为若干组,划分 ...

  6. jQuery_替换操作

    代码: <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title ...

  7. 函数-this

    1.this. 解析器在调用函数的时候,每次都会向函数内部传递进一个隐含的参数(即this): this指向一个对象,这个对象称为函数执行的上下文对象.根据函数的调用方式的不同,this会指向不同的对 ...

  8. 【Spark机器学习速成宝典】模型篇04朴素贝叶斯【Naive Bayes】(Python版)

    目录 朴素贝叶斯原理 朴素贝叶斯代码(Spark Python) 朴素贝叶斯原理 详见博文:http://www.cnblogs.com/itmorn/p/7905975.html 返回目录 朴素贝叶 ...

  9. Python学习笔记:关于脚本文件中的 if __name__ = '__main__'

    这两天自己写了一个Python脚本文件,但是直接运行这个.py之后发现里面的函数并没有执行,参考别人的代码之后,发现原来要加入以下代码: if name == 'main': 函数名1 函数名2 .. ...

  10. PHP CI 框架简单使用(二)

    我们简单认识一下CI框架的MVC.示例代码如下 //CI控制器文件Home.php <?php defined('BASEPATH') OR exit('No direct script acc ...