0
点赞
收藏
分享

微信扫一扫

消费者是根据什么策略从Master或者Slave上拉取消息的

墨春 2021-09-27 阅读 66
RocketMQ

一个关键的问题:ConsumeQueue文件也是基于os cache的

  之前的文章中写过,把数据往CommitLog中写入时,是先进入os cache缓存,而不是直接进入磁盘的,这样就可以实现Broker写入CommitLog文件的性能是内存写级别的,这样才能实现Broker超高的消息接入吞吐量。
  当写CommitLog是基于os cache来搞的,那消费者在读取消息的时候,其实还有一个重要的文件是ConsumeQueue文件,它也会被大量的消费者发送的请求进行高并发的读取,对它的读操作其实也是非常频繁的,而且同时也会极大的影响消费者拉取数据的性能。
  所以实际上Broker对ConsumeQueue文件同样也是基于os cache来进行优化的。也就是说,对Broker机器上大量的ConsumeQueue文件来说,在写入的时候还是会优先进入os cache中,并且os 自己也有个优化机制就是读取一个磁盘文件的时候,它会自动把磁盘文件的一些数据缓存到os cache中。并且大家也知道ConsumeQueue文件中村的是消息的offset,所以每个文件是非常小的,30万条消息的offset也就是只有5.72MB,所以实际上ConsumeQueue文件不会占太多的磁盘空间,他们的数据很小,基本上可以都缓存在内存的cache里。

CommitLog是基于os cache + 磁盘一起读的

因为CommitLog存放的是完整的数据,所以内容量是比较大的,一个文件就要1GB,所以整体完全有可能多达几个TB,所以这么多数据,不可能全部放在os cache中。也就是说,os cache对于commitLog来说,主要是提升文件的写入性能,当不停的写入数据的时候,很多最新写入数据的数据会停留在os cache里,比如有可能是10GB~20GB,之后os会自动把cache里比较旧的一些数据刷入磁盘里,从而腾出空间来,让新写入的数据来使用。
所以读取CommitLog完整数据的时候,有两种可能。
第一种可能:如果读取的是刚刚写入CommitLog的数据,那么大概率还会停留在os cache中,此时就顺利从os cache中读取了,性能会很高。
第二种可能:如果读取的是比较早的数据,那就可能已经被刷入磁盘了,此时就需要从磁盘上读取了。这个性能会稍微差一些。
所以就是如果消费者消费消息的速度特别快,那么此时基本上都是可以从os cache中读取的,如果消费者消费消息比较慢,比如生产者已经生产了10万条数据,消费者才消费了2万条,此时,肯定会把一些消息刷入磁盘,那么此时消费者消费到的消息基本上就是从磁盘上读取了。

Master Broker什么时候会让你从Slave Broker拉取消息

假设broker中已经写入了10万条消息,但是消费者仅仅消费了2万条消息,此时有8万条消息还没有拉取消费,然而Broker自己是知道自己这机器当前的物理内存有多大,也知道自己最大空间占里面的比例,知道自己的消息最多可以在内存里存放多少条,自己都很清楚,比如它就知道自己最大能存放5万条,然后这个时候,你过来拉取消息了,发现还有8万条数据没被消费,这8万条数据是大于它的内存里存放的最大5万条数据,并且这里面3万条数据还被刷入到了磁盘中,经过这么一系列的判断,会发现此事会很大概率的从磁盘上加载那3万条数据来进行读取,出现这种情况,它可能就会认为是自己作为master Broker负载太高了,导致没办法及时把消息给你,所以才让你消费这么慢的,这个时候,master broker在返回消息的时候,就会告你,下次你从slave Broker上拉取消息吧。

举报

相关推荐

0 条评论