非常常用的3个消息队列Kafka、RocketMQ、RabbitMQ的讲解,把使用优缺点及使用场景都有说明,值得分享,如果再有puluar的分享就更好了。

48832ab7f3098bab2730462adab1174e.png

一、三种对比

Kafka:1)基于Pull模式来处理,2)高吞吐量,3)大量数据、日志采集业务。

RocketMQ:1)金融领域而生,可靠性高,尤其订单扣款,2)业务削峰,大量交易涌入,后端无法及时

RabbitMQ:数据量没那么大,小公司优先选择

1.Kafka

优点:单机写入TPS百万条/秒、时效ms级、日志领域比较成熟

可用性高,多个副本,少数宕机,不丢数据,不会不可用

Pull方式获取消息, 有序, 控制仅被消费一次;

缺点: Kafka单机超过64个队列/分区,队列越多,load越高,发送消息响应时间变长

使用短轮询方式,实时性取决于轮询间隔时间;

不支持重试;支持消息顺序,但一台代理宕机后,就乱序

2.RocketMQ

设计时参考 Kafka做改进。阿里集团被广泛应用在订单,交易,充值,流计算,消息推送,日志流式处理,binglog分发等场景。

优点:1)吞吐量十万级、可用性高、消息可0丢失2)10亿级消息堆积,不会因堆积性能下降

3.RabbitMQ

优点:1)erlang语言的特性,mq 性能较好,高并发;吞吐量万级,MQ功能比较完备

2)健壮、稳定、易用、跨平台、支持多种语言、文档齐全;

缺点:实现机制重,吞吐量低一些

二、rocketMq高性能原因

1、生产者顺序写入

消息存储是由ConsumeQueueCommitLog配合完成。一个Topic里面有多个MessageQueue,每个MessageQueue对应一个ConsumeQueue

ConsumeQueue:记消息物理存储地址。

CommitLog:存储文件具体字节信息(文件大小默认1g,名称20位数,左边补0右边为偏移量)。消息顺序写,文件满写下一个

2、消费者随机读

先读逻辑队列consumQue中元数据,再从commitlog找消息体。但入口处rocketmq用package,可以批量地从磁盘读取,作为cache存到内存中,加速后续的读取速度。

随机读具体流程

1)Consumer20s一次负载均衡(默认分页)更新,根据Broker存的ConsumerGroupTopic信息,把MessageQueue分给不同Consumer,负载策略

2)每个MessageQueue对应一个pullRequest,全部存储到该ConsumerpullRequestQueue队列里面

3)Consumer启动独立后台PullMessageService线程,不停的尝试从pullRequestQueue.take()获取PullRequest

4)捞取到PullRequest会先做缓存校验(默认一个Queue里面缓存待处理消息个数不超过1000个,消息大小不超过100M,否则会延迟50ms再重试),从而保证客户端的缓存负载不会过高

5)PullRequest发送给Broker,如果Broker发现该Queue待处理的消息,就会直接返回给Consumer,Consumer接收响应以后,重新把该PullRequest丢到自己的pullRequestQueue队列里面,从而重复执行捞取消息的动作,保证消息的及时性

6)PullRequest发送给Broker,如果Broker发现该Queue没有待处理的消息,则会Hold住这个请求,暂不响应给Consumer,默认长轮询是5s重试获取一次待处理消息,如果有新的待处理消息则立刻ResponseConsumer,当客户端检测到消息挂起超时(客户端有默认参数 响应超时时间 20s),会重新发起PullRequest给Broker

3、消费模型

(1)push:producer发消息后,broker马上投给consumer。实时性高,但增加broker负载;如push过快,消费端出现问题

(2)pull:producer发消息后,broker等consumer来读取。主动权在消费者;但间隔不好设置,太短浪费,太消费不及时

(3)长轮询:consumer请求时,broker保持连接一段时间(默认15s),期间内有消息到达,返回给consumer;没返回空,重请求。缺点:服务端保存consumer状态,客户端过多占资源

默认pushConsumer,本质是pull+长轮询。通过长轮询达到push实时性,又有pull可控性。系统收消息后,自动处理消息offset(消息偏移量),期间有新consumer加入自动做负载均衡(集群模式下offset存在broker中; 广播模式下offset存在consumer里)。

ps:也可设pullConsumer,更灵活,代码复杂,手动维护offset、消息存储和状态。

4、zero copy

零拷贝技术有mmap(小文件)及sendfile(大文件),MMQ发送消息通常都很小,rocketmq就以mmap+write实现

三、为什么kafka比RocketMQ吞吐量更高

kafka的Producer:小消息缓存合并(异步),到一定数量批量发Broker

减少网络io,提高发送性能,但发送者宕机,消息丢失,提高io性能降低可靠性

RocketMQ无法用同样方式

因为用的Java语言,缓存过多会GC

Producer调send(),未发送到Broker,返回成功,宕机,消息丢

Producer每台机器多线程发送,单Producer每秒数据有限,不可能上万缓存完全可由上层业务完成。

四、为什么选择RocketMQ

broker里topic的partition数过多,kafka性能 < rocketMq都用文件存储

1、kafka: 一个分区一个文件,topic多,分区总量也多,对消息刷盘时,文件竞争磁盘,出现性能的下降。顺序读写,一分区最多只被一线程消费

2、rocketMq:所有队列都存一个文件中,每个队列消息量小,topic的增加对rocketMq性能影响小

五、为什么kafka 用zk,rocket mq用自研的NameServer?

与nameServer相比,zookeeper:

1.复杂性:zk:基于CAP,宕机选举,选举耗时;

nameServer:代码量少,节点间互不通信,无法复制。

2.可用性:zk :CP,牺牲可用性

nameServer:部署多台broker实现高可用:没宕机时,轮询队列,发消息;宕机:接下来5分钟跳过BrokerA,选其他broker中队列,发消息,不选举

3、路由注册信息:

zk:数据只写主节点,就复制到从

NameServer:broker启动时,轮询nameServer列表,与每个nameServer长连接,发起注册请求。

1、维护Broker列表,用来动态存储Broker信息。

2、Broker和NameServer心跳检测,30s发给NameServer Broker信息。NameServer会更新时间,最新与当前超过120s,则进行路由剔除

3、Topic路由注册中读写锁:对broker表允许并发读,串行写


文章来源:https://www.jianshu.com/p/ef212ea15520

Logo

Kafka开源项目指南提供详尽教程,助开发者掌握其架构、配置和使用,实现高效数据流管理和实时处理。它高性能、可扩展,适合日志收集和实时数据处理,通过持久化保障数据安全,是企业大数据生态系统的核心。

更多推荐