背景

  本公司是.Net项目,在.Net可选的MQ比较少,主要Kafka和RabbitMQ,RabbitMQ我也是使用多年了,最近的Kafka广告与流行度打得使我也是无法无视,因此也是花了点时间收集了资料做了些对比。

  此外有个小插曲,当我形成了文档让老板兼CTO对比决策后,他打算上阿里云买MQ服务。我当时给他开了个玩笑:您这价钱把我请回来,而且公司还有运维,其实完全可以自己维护,要不我来负责,你把这每个月的MQ费用给我加工资得了。当我下楼买了支维他柠檬茶后,他决定由我们自己搭建RabbitMQ。这个决定跟我的想法差不多,原因主要两点:运维起来方便,吞吐没有特别高。

RabbitMQ模型

名词 描述
Queue 用于存储消息,消费者直接绑定Queue进行消费消息
Exchange 生产者将消息发送到Exchange,由交换器将消息通过匹配Exchange Type、Binding Key、Routing Key后路由到一个或者多个队列中。
Exchange Type Direct、Fanout、Topic、Headers
Routing Key 生产者发送消息给Exchange会指定一个Routing Key。
Binding Key 在绑定Exchange与Queue时会指定一个Binding Key
  • Exchange在声明时会绑定Queue和Binding Key,当Exchange收到消息会根据消息的
  • Routing Key与Exchange Type、Binding Key进行匹配,最后会路由到相关的队列当中。
    • Fanout,将消息发送到与该交换器所绑定的所有队列中,与Routing Key、Bind Key无关,这就是广播模式。
    • Topic,通过对消息的Routing Key和Exchange、Queue进行匹配,将消息路由给一个或多个队列,以此来达到发布/订阅模式。
    • Direct,把消息路由到哪些Bind Key和Routing Key完全匹配的队列中。
    • Headers,不依赖与路由键的匹配规则,基本用不上。
  • 消费者会直接订阅Queue里的消息进行消费,多个消费者订阅同个Queue会形成消息竞争状态,以此达到负载均衡作用。

Kafka模型

名词 描述
Topic 队列是通过Topic进行隔离的,生产者发送消息必须指定Topic
Broker 一个Kafka Server的被称为一个Broker。
Partition 每个Topic可以包含多个Partition,多个Partition会平均分配给同一个Consumer Group里的不同Consumer进行消费
Consumer Group 不在同一个Group 的Consumer能重复消费同一条消息(订阅),相同Group的Consumer存在消费竞争(负载均衡)
  • Kafka与RabbitMQ比没有Exchange的概念,生产者直接发消息Topic(队列)。
  • Kafka的订阅者是通过消费组(Consumer Group)来体现的,每个消费组都可以重复消费Topic一份完整的消息,不同消费组之间消费进度彼此不受影响。例如Message1能被Consumer Group 1和Consumer Group2里的消费者都消费一次。
  • 消费组中包含多个消费者,同个Group的消费者之间是竞争消费的关系。例如Message2只能够被Consumer Group里某一个Consumer只消费一次。
  • Kafka具有消息存储的功能,消息被消费后不会被立即删除,因为需要被不同的Consumer Group多次消费同个消息,因此会在Topic维护一个Consumer Offset,每消费成功Offset自增1.

功能对比

对比项 RabbitMQ Kafka
吞吐量
有序性 全局有序性 分区有序性
消息可靠性 多策略组合 消息持久化
流处理 不支持 支持
时效性
运维便捷度
系统依赖 zookeeper
Web监控 自带 第三方
优先级队列 支持 不支持
死信 支持 不支持
客户端支持 支持多种语言
社区生态
安全机制 (TLS/SSL、SASL)身份认证和(读写)权限控制
消息回溯 支持 不支持

对比描述

共同点

RabbitMQ与Kafka都有很好的客户端语言支持、安全机制与生态支持。

性能

Kafka的诞生的是处理高并发日志的,吞吐量比较高,每秒请求数达到数十万量级,而RabbitMQ每秒请求数则为万级别,有测试报告指出Kafka是RabbitMQ的10倍以上性能。

运维便捷

RabbitMQ相对比较方便,可以使用yum或者docker安装,自带Web管理UI,没有额外的依赖,除了需要做镜像队列外需要引入HAproxy。

Kafka则需要依赖Zookeeper,也没有自带的管理工具,可以使用第三方的Kafka Eagle代替,Kafka Manager过于难用,另外Kafka没有yum安装,docker镜像也是社区人员自己建的。

有序性

RabbitMQ理论上是全局有序性的,但是由于【发后既忘】+【自动确认】机制的原因,如果在同个队列的多个消费者做相同的业务处理时,他们的各自的执行任务无法保证有序完成。如果确保100%有序可以使用【非自动确认】,但会影响消费性能。

Kafka支持分区有序性,如果对有序性有严格要求可以设置单个Partition,可是单个Partition并发性比较低,因此在多个Partition情况下可以根据业务指定key把相关的消息路由到同一个Partition,例如相同UserId行为信息可以到Partition 1进行处理。

时效性

Kafka基本上无论在客户端还是服务端都是以【异步批量】的机制进行处理,通俗的讲就是先攒起来一堆消息,到了某个阀值再发送,也会导致一些消息可靠性与消息有时效上的问题,当然可以通过各种配置策略进行解决。

消息回溯

Kafka在消费完了消息后不会立即删除,只会修改offset,如果之前部分业务消费失败了可以重新设置offset进行重新消费。

RabbitMQ则是[发后既忘]的机制,一但消费者确认消息则删除,但是可以通过死信进行补偿消费。此外RabbitMQ在队列消息堆积多的情况下性能表现不佳,所以尽可能的及时消费消息。

特色功能

RabbitMQ具有死信的功能,可以通过死信形成重复消费与延时发送。

Kafka具有流处理功能,可以收集用户的行为日志进行存储与分析。

Kafka为什么快?

关键核心技术点:

  • 异步批量处理
  • 磁盘顺序读写
  • 操作系统PageCache缓存数据
  • 零拷贝加速消费

Kafka的诞生就是为了高并发日志处理的,那么在他整个机制里使用了很多批量、异步、缓存。例如生产者客户端,他会积累一定量(条数、大小)的消息,再批量的发给kafka broker,如果在这段时间客户端服务挂了,就等于消息丢失了。当broker接受到了消息后,还有一堆骚操作-异步刷盘,也就是生产者发送给broker之后他是记录在缓存的,每隔一段时间才会持久化到磁盘,假如这段真空期broker挂了,消息也是丢了。

Kafka是否消息不可靠?

Kafka快是因为牺牲了消息可靠换取回来的性能,在最早期版本的确没提供消息可靠的策略,经过多个版本迭代后的功能完善,已经不存在这种旧观念。那么可靠的关键点有以下:

生产者

设置ack:

  • 0:producer不等待broker的ack,broker一接收到还没有写入磁盘就已经返回,可靠性最低;
  • 1:producer等待broker的ack,partition的leader刷盘成功后返回ack,如果在follower同步成功之前leader故障,那么将会丢失数据,可靠性中;
  • -1:producer等待broker的ack,partition的leader和follower全部落盘成功后才返回ack,数据一般不会丢失,延迟时间长但是可靠性高

消费者

设置enable.auto.commitrue,不管执行结果如何,消费者会自动提交offset。

false,需要用户需要手动提交offset,可以根据执行结果具体处理offset

RabbitMQ单节点部署

安装

yum install -y rabbitmq-server

开放相关端口

firewall-cmd --permanent --add-port=15672/tcp
firewall-cmd --permanent --add-port=5672/tcp
firewall-cmd --reload

启动服务

service rabbitmq-server start

启动web管理界面

rabbitmq-plugins enable rabbitmq_management

增加访问admin用户,默认用户guest只能本地访问。

rabbitmqctl add_user admin 123456

设置admin用户为管理员角色

rabbitmqctl set_user_tags admin administrator

设置默认admin用户访问权限

rabbitmqctl set_permissions -p "/" admin "." "." ".*"

重启服务

service rabbitmq-server restart

浏览器访问:http://IP:15672

Kafka单节点部署

Zookeeper部署

下载Zookeeper并启动

docker run -d --restart always --name zookeeper -p 2181:2181 -v /root/zookeeper/data:/data -v /root/zookeeper/conf:/conf -v /root/zookeeper/logs:/logs zookeeper:3.6.1

开放2181端口

firewall-cmd --permanent --add-port=2181/tcp
firewall-cmd --reload

Kafka服务部署

下载kafka 镜像并启动

docker run -d --name kafka -p 9092:9092 -e KAFKA_BROKER_ID=1 -e KAFKA_ZOOKEEPER_CONNECT=192.168.88.139:2181 -e KAFKA_ADVERTISED_HOST_NAME=192.168.88.141 -e KAFKA_ADVERTISED_PORT=9092 wurstmeister/kafka:2.12-2.5.0

创建目录并拷贝

mkdir /root/kafka
docker cp kafka:/opt/kafka/config /root/kafka/config

删除原有的容器并重新创建

docker stop kafka
docker rm kafka docker run -d --name kafka -p 9092:9092 -e KAFKA_BROKER_ID=1 -e KAFKA_ZOOKEEPER_CONNECT=192.168.88.139:2181 -e KAFKA_ADVERTISED_HOST_NAME=192.168.88.141 -e KAFKA_ADVERTISED_PORT=9092 -v /root/kafka/config: /opt/kafka/config wurstmeister/kafka:2.12-2.5.0

开放9092端口

firewall-cmd --permanent --add-port=9092/tcp
firewall-cmd --reload

Kafka-eagle

下载jdk依赖

yum -y install java-1.8.0-openjdk*

下载kafka-eagle-bin包

wget -o kafka-eagle-bin.tar.gz https://codeload.github.com/smartloli/kafka-eagle-bin/tar.gz/v2.0.1

解压

tar -zxvf kafka-eagle-bin.tar.gz
tar -zxvf kafka-eagle-bin-2.0.1/kafka-eagle-web-2.0.1-bin.tar.gz
mv kafka-eagle-web-2.0.1 kafka-eagle

添加环境变量

vim /etc/profile

export JAVA_HOME=/usr
export KE_HOME=/etc/kafka-eagle
export PATH=$PATH:$KE_HOME/bin:$JAVA_HOME/bin

生效环境变量

source /etc/profile

修改Kafka-eagle配置

cd /etc/kafka-eagle/conf
vim system-config.properties #注释
#cluster2.zk.list=xdn10:2181,xdn11:2181,xdn12:2181
#cluster2.kafka.eagle.offset.storage=zk #cluster1.zk.acl.enable=false
#cluster1.zk.acl.schema=digest
#cluster1.zk.acl.username=test
#cluster1.zk.acl.password=test123 修改
kafka.eagle.zk.cluster.alias=cluster1
cluster1.zk.list=192.168.88.139:2181
kafka.eagle.metrics.charts=true kafka.eagle.driver=org.sqlite.JDBC
kafka.eagle.url=jdbc:sqlite:/etc/kafka-eagle/db/ke.db
kafka.eagle.username=root
kafka.eagle.password=root

启动kafka-eagle服务

cd /etc/kafka-eagle/bin
chmod +x ke.sh
ke.sh start

开启防火墙

firewall-cmd --permanent --add-port=8048/tcp
firewall-cmd --reload

浏览器访问:http://IP:8048

阿里云费用

以下截图基本以最低配置。

Kafka按量付费

Kafka包月

RabbitMQ包月

RabbitMQ与Kafka选型对比的更多相关文章

  1. RabbitMQ 和 Kafka

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

  2. 消息中间件面试题31道RabbitMQ+ActiveMQ+Kafka

    消息中间件面试题31道RabbitMQ+ActiveMQ+Kafka 前言 文章开始前,我们先了解一下什么是消息中间件? 什么是中间件? 非底层操作系统软件,非业务应用软件,不是直接给最终用户使用的, ...

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

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

  4. 我为什么要选择RabbitMQ ,RabbitMQ简介,各种MQ选型对比(转载)

    转载自:https://www.sojson.com/blog/48.html 前言: MQ 是什么?队列是什么,MQ 我们可以理解为消息队列,队列我们可以理解为管道.以管道的方式做消息传递. 场景: ...

  5. 为什么要选择RabbitMQ ,RabbitMQ简介,各种MQ选型对比

    原文:https://www.sojson.com/blog/48.html 前言: MQ 是什么?队列是什么,MQ 我们可以理解为消息队列,队列我们可以理解为管道.以管道的方式做消息传递. 场景: ...

  6. RabbitMQ和Kafka对比

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

  7. MQ选型对比RabbitMQ RocketMQ ActiveMQ

    原文:MQ选型对比RabbitMQ RocketMQ ActiveMQ 几种MQ产品说明:     ZeroMQ :  扩展性好,开发比较灵活,采用C语言实现,实际上他只是一个socket库的重新封装 ...

  8. RabbitMQ和Kafka对比以及场景使用说明

    我目前的项目最后使用的是RabbitMQ,这里依然是结合网上大神们的优秀博客,对kafka和rabbitmq进行简单的比对.最后附上参考博客. 1.架构模型 rabbitmq RabbitMQ遵循AM ...

  9. RabbitMQ 和 Kafka 的消息可靠性对比

    RabbitMQ和Kafka都提供持久的消息保证.两者都提供至少一次和至多一次的保证,另外,Kafka在某些限定情况下可以提供精确的一次(exactly-once)保证. 让我们首先理解一下上述术语的 ...

随机推荐

  1. rlpyt(Deep Reinforcement Learning in PyTorch)

    rlpyt: A Research Code Base for Deep Reinforcement Learning in PyTorch Github:https://github.com/ast ...

  2. Python1--简介及基础语法

    0. 简介 Python易于学习的编程语言,有很多现成的第三方库可以调用,不用重复造轮子,老话说:"人生苦短,我用 Python" 1. 安装Python Mac:brew ins ...

  3. 方差分析、T检验、卡方分析如何区分?

    差异研究的目的在于比较两组数据或多组数据之间的差异,通常包括以下几类分析方法,分别是方差分析.T检验和卡方检验. 三个方法的区别 其实核心的区别在于:数据类型不一样.如果是定类和定类,此时应该使用卡方 ...

  4. 牛客网PAT练兵场-组个最小数

    题解:从小到大输出 题目地址:https://www.nowcoder.com/questionTerminal/86ede762b450404dbab59352963378e9 /** * *作者: ...

  5. 做SEO必须制定超越竞争对手网站的方案

    http://www.wocaoseo.com/thread-131-1-1.html       从开始终学习SEO技术,到现在半年过去了,其间也做了几个站,可是赚钱的并不多,有流量的也不多,虽然说 ...

  6. 以vue+TreeSelect为例,如何将扁平数据转为tree形数据

    // 目标:将后台返回的扁平数据,根据parentId转为下拉tree <el-form-item label='下拉选择数据'> <tree-select v-model='tre ...

  7. 一键洞察全量SQL ,远离性能异常

    随着云数据库业务规模不断扩大,用户对安全审计.性能智能分析等高级特性的要求越来越高.如何安全审计SQL?如何快速定位性能异常?如何保护数据库安全?是每个云厂商不得不思考的问题. 华为云DAS服务提供的 ...

  8. hdu6075 2019CCPC网络选拔赛1004 path

    题意:给定一个带权有向图,有q组询问,每次询问在有向图的所有路径中,第k小的路径权值 解题思路:因为k最大只有5e4,考虑暴力搜索出前maxk小的路径并用数组记录权值,然后就可以O(1)查询. 具体实 ...

  9. 利用递归方法实现链表反转、前N个节点反转以及中间部分节点反转

    一.反转整个链表 问题:定义一个函数,输入一个链表的头节点,反转该链表并输出反转后链表的头节点. 示例: 输入: 1->2->3->4->5->NULL 输出: 5-&g ...

  10. Macos 编译运行调试Mysql源代码

    准备编译工具Clion 下载地址 工具是macos用的系统 百度云盘下载地址(密码: 7dus) 下载mysql源码 Mysql源码下载地址 下载boost boost下载地址 前期准备工作 MySQ ...