RocketMQ-消费者消费消息的策略

无天有壁纸 2024-05-05 22:38:23
消费消息,可以从Master Broker拉取,也可以从Slave Broker拉取,那到底什么时候从Master Broker拉取,什么时候从Slave Broker拉取? 之前有提到刚开始消费者都是从Master Broker机器上去拉取消息的,然后如果Master Broker机器觉得自己负载比较高,就会告诉消费者机器,下次可以从Slave Broker机器去拉取。 ConsumeQueue文件也是基于os cache的ConsumeQueue会被大量的消费者发送的请求给高并发的读取,所以ConsumeQueue文件的读操作是非常频繁的,而且同时会极大的影响到消费者进行消息拉取的性能和消费吞吐量。 所以实际上broker对ConsumeQueue文件同样也是基于os cache来进行优化的。 也就是说,对于Broker机器得到磁盘上的大量的ConsumeQueue文件,在写入的时候也是优先进入os cache中的。 而且之前也了解到ConsumeQueue文件主要是存放消息的offset,所以每个文件很小,30万条消息的offset就只有5.72MB而已,所以实际上ConsumeQueue文件他们是不占用多少磁盘空间的,他们整体数据量很小,几乎可以完全被os 缓存在内存cache中。 所以实际上在消费者机器拉取消息的时候,第一步大量的频繁读取ConsumeQueue文件,几乎可以说就是跟读内存里的数据的性能是一样的,通过这个就可以保证数据消费的高性能以及高吞吐。 CommitLog是基于os cache + 磁盘一起读取的在进行消息拉取的时候,先读os cache里的少量ConsumeQueue的数据,这个性能是极高的,然后第二步就是要根据你读取到的offset去CommitLog里读取消息的完整数据了。 那么这个从CommitLog里读取消息完整数据是如何读取的?是从os cache里读取?还是从磁盘文件里读取? 答案是:两者都有。 因为CommitLog是用来存放消息的完整数据的,所以内容量是很大的,毕竟他一个文件就要1GB,所以整体完全有可能多大几个TB。 所以这么多的数据,不可能完全都放在os cache中。因为os cache用的也是机器的内存,一般也就几十个GB而已,何况Broker自身的JVM也要用一些内存,留给os cache的内存只是一部分罢了。所以os cache对于CommitLog而言,是无法把他全部数据都放在里面给你读取的。 也就是说,os cache对于CommitLog而言,主要是提升文件写入性能,当你不停的写入的时候,很多最新写入的数据都会先停留在os cache里。之后os 会自动把cache里比较旧的一些数据刷入磁盘,腾出来空间给新写入的数据。 所以最终结论就是当你拉取消息的时候,可以轻松从os cache里读取少量的consumeQueue文件里的offset,这个性能是极高的,但是当你去CommitLog文件里读取完整消息数据的时候,会有两种可能: 第一种:如果你读取的是刚刚写入CommitLog的数据,那么大概率还停留在os cache中,此时可以顺利地直接从os cache里读取CommitLog中的数据。这个就是内存操作,性能是很高的。 第二种:你也许读取的是比较早之前写入CommitLog的数据,这些数据早就被刷入磁盘了,已经不在os cache里了,那么此时你就只能从磁盘上的文件里读取了,这个性能是比较差一些。 什么时候会从os cache读,什么时候会从磁盘读?如果你的消费者机器一直快速的在拉取和消费处理,紧紧的跟上了生产者写入broker的消息速率,那么你每次拉取几乎都是在拉取最近人家刚写入CommitLog的数据,那几乎都是在os cache里。 但是如果broker的负载很高,导致你拉取消息的速度很慢,或者是你自己的消费者机器拉取到一批消息之后处理的时候性能很低,处理的速度很慢,这都会导致你跟不上生产者写入的速率。 比如人家都写入10万条数据了,结果你才拉取了2万条数据,此时有5万条最新的数据是在os cache里,有3万条你还没有拉取的数据是在磁盘里,那么当后续你再拉取的时候,必然很大概率是从磁盘里读取早就刷入到磁盘的3万条数据。
0 阅读:2

无天有壁纸

简介:感谢大家的关注