RocketMq架构

一.概述

rocketMq是消息中间件,通常用于业务上的解藕,消峰。

二.竞品对比

特性ActiveMQRabbitMQRocketMQKafka
单机吞吐量万级,比 RocketMQ、Kafka 低一个数量级同 ActiveMQ10 万级,支撑高吞吐10 万级,高吞吐,一般配合大数据类的系统来进行实时数据计算、日志采集等场景
topic 数量对吞吐量的影响topic 可以达到几百/几千的级别,吞吐量会有较小幅度的下降,这是 RocketMQ 的一大优势,在同等机器下,可以支撑大量的 topictopic 从几十到几百个时候,吞吐量会大幅度下降,在同等机器下,Kafka 尽量保证 topic 数量不要过多,如果要支撑大规模的 topic,需要增加更多的机器资源
时效性ms 级微秒级,这是 RabbitMQ 的一大特点,延迟最低ms 级ms 级以内
可用性高,基于主从架构实现高可用同 ActiveMQ非常高,分布式架构非常高,分布式,一个数据多个副本,少数机器宕机,不会丢失数据,不会导致不可用
消息可靠性有较低的概率丢失数据基本不丢经过参数优化配置,可以做到 0 丢失同 RocketMQ
功能支持MQ 领域的功能极其完备基于 erlang 开发,并发能力很强,性能极好,延时很低MQ 功能较为完善,还是分布式的,扩展性好功能较为简单,主要支持简单的 MQ 功能,在大数据领域的实时计算以及日志采集被大规模使用

从对比中可以看出,rocketMq整体吞吐量相对比较优秀单机可达10w,同时在参数在实时刷盘的时候可以做到0丢失,在架构上也是分布式架构。

相比kafka,rocketMq支持的topic数量在几百到几千,而kafka在几十到几百就会性能下降。

同时rocketmq还支持消息事务,kafka则功能比较简单适用于大数据实时计算或日志采集场景。

而activeMq及rabbitMq无论从吞吐量及高可用性来讲都赶不上rocketMq。rabbitMq最多做到镜像集群模式,此种模式下这个queue所有数据可在多个集群结点上存储,但是这个queue如果消息量很多突破了单机broker存储的限制,此时就会有问题。

综上分析rocketmq在吞吐量,分布式架构,topic数量上有较大的优势,同时是阿里的中间件整体经历过大流量复杂场景的验证比较可靠。

rocketMq与kafka架构上区别:

kafka元数据存储在kafaController结点,对应分区的master挂了后用zk进行选举。

从物理文件上看每个时刻rocketMq对应就是一个commitLog文件。而kafka的物理文件由topic的partion数量决定,一个partion就是一个物理文件。

kafka单机支持的队列数远小于rocketMq,rocketmq理论支持1万个以上。

kafka超过topic超过一千个整体性能就会很差,这是因为kafka多个topic是多个物理文件,因些在写消息的时候整体kafka服务进程就变成随机写了。而rocketMq不会有这个问题因为所有topic都是一个文件。

kafka架构:

三.架构

1.逻辑架构

2.部署架构

rocketMq是分布式的,可以支持多个master slave组成的集群。

但slave只在master消费读取压力比较高时才会触发从slave取数据,且如果master挂了并不会将slave升级成master。

在部署master及slave时,配置master写消息时是同步还是异步写slave。

name sevrer集群保存了所有的broker地址,消费者及生产者是在本地保存了name server集群地址。

四.各功能模块深入

1.消息发送与消费

当消息发送者发送消息给broker的时候,broker会存储消息到commitLog中。然后会异步构建consumerQueue及消息索引服务。

这样的好处是写操作能保证是磁盘的顺序写从而保证了写的高效能。

而对于消费消息这块则是从consumerQueue拉取数据,consumerQueue保存了一个消息在commitLog中的offset位置及消息大小,所以一次消息消费需要2次读取。consumerQueue这样设计因为存储的内容少,所以整体可以利用操作的系统的PageCache来加快消息的消费速度。

在消息消费时,如果存在slave的情况,并且发现消费者拉取的是磁盘上的内容时此时将consumer的消费重定向到slave服务器。这里不需要担心slave的写性能会减少,因为slave在同步时是同步一批数据,如1M的数据,整体写入量要远远大于master的写入。

这里补充下传统io读取的步骤:

从图中可以看到pageCache相当于一个缓存如果在这个缓存存在则直接从这个缓存读取数据从而加速消费的速度。

但这个图中使用传统io的读取如果没命中缓存则会涉及2次内存拷贝:文件系统到内核,内核到用户空间堆内存。

rcoketMq为了提升性能使用了Mmap零拷贝能力,去除了内核到用户空间堆内存的拷贝。

如下图:

当使用java的mmap后,用户进程空间与内核空间pageCache做了映射。

rocketMq用户态情况下直接从pageCache取数据,不需要再拷贝到用户进程堆空间中,这样做就减少了从内核到用户堆空间的拷贝耗时。

2.发送者负载均衡

目的:保证topic下各queue的消息量能够均衡。

负载均衡策略一般有:轮循。如queue有10个,那发消息先到q1然后q2等等。

3.消费者负载均衡

目的:保证一个topic下同一个消费组下的消费者消费queue的数量能够均衡。

策略:平均,环形分配,一致性hash,机房分配。

  • 平均:先按平均数=queue数量/消费者数量按顺序分配。如果平均数不能整除则先按平均数进行分配,分配后不能整除溢出部分按顺序逐个分配。
  •  环形

依次按消费者顺序每次分配一个队列。

  • 一致性hash

优:解决consumer变化导致的

queue及consumer的hashCode放到数组环上。然后顺时针查询对应queue离环上哪个consumer最近,最近的consumer就是这个queue要被分配。

4.rebalance机制

是什么:queue被哪个消费者消费。

什么时候发生:消费者或队列数量发生变化。

rebalance导致的问题:

消息暂停:rebalance完成后原consumer才能继续消费;

消费重复:新加的消费者被分配给到之前由另外一个consumer消费的queue,由于之前消费者是异步提交消费的offset,所以导致重复消费;

消息突刺:rebalance时间过长导致消息积压&消费重复,当rebalance结束后消费者面积大量消息消费。

流程

  • 获取这台消费者client上所有topic
  • 循环对每个topic进行rebalance
  • 对topic下获取到的queue的数据进行排序,对获取到这个topic下所有消费者id进行排序。
  • 进行预分配:调用不同策略实现。如平均策略(默认),环形策略等。
  • 持久化预分配结果:新增给这个消费者的queue需要加入并开启消费,不属于这个消费者的queue则需要丢弃不再消费。
  • 分配完后的处理:对于push模式主要是流控处理,对于pull就是调用自定义的messageListener。

预分配中的一致性hash负载算法:

设置一个物理消费者对应n个虚拟结点,默认是10.

初始时将消费者物理结点换算成n个虚拟结点放入到treeMap:key为虚拟结点id,value是虚拟结点对象VirtualNode。VirtualNode会关联物理结点。

然后看某个queue对应的处理消费者物理结点这个就是从虚拟结点treemap中根据queue id hashCode进行获取。思路是:获取treemap中大于等于queue id hashCode的虚拟结点列表。然后取出第一个消费者物理结点就是当前queue对应的消费者结点。由于treemap的有序性这步就相当于实现了从消费者环中顺时针获取第一个消费者结点的逻辑。

5.push与pull实现

rocketmq的push也是根据长连接pull实现。push与pull区别:push使用上更简单只需要实现一个listener。pull则需要实现:获取queue,拉取消息以及设置维度消息消费offset。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值