RocketMQ是什么(二)

7.RocketMQ关键特性

(1)单机支持1万以上持久化队列



1.所有数据单独存储到一个Commit Log,完全顺序写,随机读。

2.对最终用户展现的队列实际只存储消息在Commit Log的位置信息,并且串行方式刷盘。

这样好处:

a、队列轻量化,单个队列的数据量非常少。

b、对磁盘的访问串行化,避免磁盘竞争,不会因为队列增加导致IO wait 增高。

每个方案都有缺点,它的缺点如下:

(a)写虽然完全是顺序写,但是读却变成了完全的随机读、

(b)读一条消息,会先读Consume Queue,再读Commit Log,增加了开销。

(c)要保证Commit Log 与Consume Queue完全的一致,增加了编程的复杂度。

(2)刷盘策略

RocketMQ所有的消息都是持久化的,先写入系统PAGECACHE,然后刷盘,可以保证内存与磁盘都有一份数据,访问时,直接从内存读取。

(a)异步刷盘



(b)同步刷盘



同步刷盘与异步刷盘的唯一区别是异步刷盘写完PAGECACHE直接返回,而同步刷盘需要等待刷盘完成后才能返回。

同步刷盘流程如下:

(1)写入PAGECACHE后,线程等待,通知刷盘线程刷盘。

(2)刷盘线程刷盘完成后,唤醒前端等待线程,可能是一批线程。

(3)前端等待线程向用户返回成功。


3.消息查询

(a)按照Message Id查询消息

  


MsgId总共16字节,包含消息存储主机地址,消息Commit Log offset,从MsgId中解析出Broker的地址和Commit Log Offset的偏移地址,然后按照存储格式所在位置消息buffer解析成一个完整的消息。

(b)按照Message key查询消息



1.根据查询的key的hashcode%slotNum得到具体地槽的位置(slot是最大槽数,图中为5000000)

2.根据slotValue(slot位置对应的值)查找到索引项列表的最后一项(倒序排序,slotVlaue总是指向最新一个索引项)

3.遍历索引项列表返回查询时间范围内的结果集(默认一次最大返回32条记录)

4.Hash冲突:寻找key的slot位置时相当于执行了两次散列函数,一次key的hash,一次key的hash值取模,因此存在两次冲突的情况:a、key的hash值不同但模数相同,此时查询的时候会再比较一次key的hash值(每个索引项保存了key的hash值),过滤掉hash值不相等的项。第二种,hash值相同key不同,出于性能的考虑冲突的监测放到客户端处理(key原始值是存储在消息文件中,避免对数据文件的解析),客户端比较一次消息体的可以是否相同。

5.存储:为了节省空间索引项中存储的时间是时间差值(存储时间-开始时间,开始时间存储在索引文件头中,整个索引文件是定长的,结构也是固定的)

4.服务器消息过滤

RocketMQ的消息过滤方式有别与其他消息中间件,是在订阅时,再做过滤,先看下Consumer Queune结构


(1)在Broker端进行Message Tag比对,先遍历Consume Queue,如果存储的Message Tag 与订阅的Message Tag不符合,则跳过,继续比对下一个,符合则传输给Consumer,注意,Message Tag是字符串形式,ConsuemerQueue中存储的是其对应的hashcode,比对时也是hashcode。

(2)Consumer收到过滤后的消息后,同样也要执行在Broker端的操作,但是比对的是真实的Message Tag字符串,而不是hashcode。

为什么过滤要这样做?

a、Message Tag存储Hashcode,是为了在Consume Queue定长方式存储,节约空间。

b、过滤过程中不会访问Commit Log数据,可以保证堆积情况下也能高效过滤。

c、即使存在hash冲突,也可以在Consumer端进行修正,保证万无一失。、


5.长轮询Pull

RocketMQ的consumer都是从Broker拉消息来消费,但是为了做到实时收消息,RocketMQ使用长轮询方式,可以保证消息实时性同Push方式一致,这种长轮询方式类似于Web QQ收发消息机制,

6.顺序消息原理


顺序消息缺陷:

发送顺序消息无法利用集群FailOver特性

消费顺序的并行度依赖于队列数量

队列热点问题,个别队列由于哈希不均导致消息过多,消费速度跟不上,产生消息堆积问题

遇到消息失败的消息,无法跳过,当前对列消费暂停

7.事务消息



8.发送消息负载均衡


5个队列可以部署在一台机器上,也可以分别部署在5台不同的机器上,发送消息通过轮询队列的方式发送,每个队列接收平均的消息量,通过增加机器,可以水平扩展队列容量。也可以自定义方式选择发往哪个队列。


9.订阅消息负载均衡


如图,若有5个队列,2个consumer,那么第一个Consumer消费3个队列,第二consumer消费2个队列。这样可以达到平均消费的目的,可以水平扩展Consumer来提高消费能力,但是Consumer数量要小于等于队列数量,如果Consumer超过队列数量,那么多余的Consumer将不能消费消息


消息堆积问题

 



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值