美文网首页
25、消费者到底是根据什么策略从Master或Slave上拉取消

25、消费者到底是根据什么策略从Master或Slave上拉取消

作者: 呢看了看 | 来源:发表于2020-07-07 12:02 被阅读0次

【1】Broker读写分离架构的回顾   

    消息消费,可以从Master Broker拉取,也可以从Slave Broker拉取。具体是看机器负载来决定。刚开始消费者都是连接到Master Broker机器去拉取消息的,然后如果Master Broker机器觉得自己负载比较高,就会告诉消费者机器,下次可以从Slave Broker机器去拉取。

【2】CommitLog基于os cache提升写性能的回顾

    broker收到一条消息,会写入CommitLog文件,但是会先把CommitLog文件中的数据写入os cache中(操作系统管理的缓存)去。然后os自己有后台线程,过一段时间后会异步把os cache缓存中的CommitLog文件的数据刷入磁盘中去。就是依靠这个写入CommitLog时先进入os cache缓存,而不是直接进入磁盘的机制,就可以实现broker写CommitLog文件的性能是内存写级别的,才能实现broker超高信息接入吞吐量。

【3】 ConsumeQueue文件也是基于os cache的

        ConsumeQueue会被大量的消费者发送的请求给高并发的读取,所以ConsumeQueue文件的操作是非常频繁的,而且同时会极大的影响到消费者进行消息拉取的性能和消费吞吐量。

       所以实际上broker对ConsumeQueue文件同样也是基于os cache来进行优化的。也就是说,对于Broker机器的磁盘上的大量的ConsumeQueue文件,在写入的时候也都是优先进入os cache的。而且os自己有一个优化机制,就是读取一个磁盘文件的时候,他会自动把磁盘文件的一些数据缓存到os cache中。

    ConsumeQueue文件主要是存放消息的offset,所以每个文件很小,30万条消息的offset就只有5.72M而已,所以实际上ConsumeQueue文件们是不占用多少磁盘文件的,他们整体数据量很小,几乎可以完全被os缓存在内存cache中。所以实际上在消费者机器拉取消息的时候,第一步大量的频繁读取ConsumeQueue文件,几乎可以说就是跟读内存里的数据的性能是一样的,通过这个就可以保证数据消费的高性能以及高吞吐。

【4】 CommitLog是基于os cache+磁盘一起读取的

        在进行消息拉取的时候,先读os cache里的少量ConsumeQueue的数据,这个性能是极高的,然后第二步就是根据你要读取到的offset去CommitLog里读取消息的完整数据了。这个从CommitLog里读取消息的完整数据是如何读取的,从os cache里读取?还是从磁盘里读?答案是:两者都有。

    因为CommitLog是用来存放消息的完整数据的,所以内容量是是很大的,毕竟一个文件就要1GB,所以整体完全可能多达几个TB,这么多的数据,不可能是都放在os cache的。

    因为os cache用的是机器的内存,一般多也就几十个GB而已。何况,Broker自身的JVM也要用一些内存,留个os cache的内存只是一部分罢了,比如10GB~20GB的内存,所以os cache对于CommitLog而言,是无法把他全部数据都放在里面给你读取的。

    也就是说,os cache对于CommitLog而言,主要是提升文件写入性能,当你不停地写入的时候,很多最新写入的数据都会先停留在os cache里,比如这可能有10GB~20GB的数据。之后os会自动把cache里比较旧的一些数据刷入磁盘里,腾出来空间给更新写入的数据放在os cache里,所以大部分数据可能高达几个TB都是在磁盘上的。

    所以最终结论来了,当你拉取消息的时候,可以轻松从os cache里读取少量的ConsumeQueue文件里的offset,这个性能是极高的,但是当你去CommitLog文件里读取完整消息数据的时候,会有两种可能。

    第一种可能,如果你读取的是那种刚刚写入CommitLog的数据,那么大概率他们还停留在os cache中,此时你可以顺利的直接从os cache里读取CommitLog中的数据,这个就是内存读取,性能是很高的。

    第二种可能,你也许读取的是比较早之前写入CommitLog的数据,那些数据早就被刷入磁盘了,已经不在os cache里了,那么此时你就只能从磁盘上的文件里读取了,这个性能是比较差一些的。

【5】 什么时候会从os cache读?什么时候会从磁盘读?

   什么时候会从os cache读?什么时候会从磁盘里读?

        如果你的消费者机器一直快速的在拉取和消息处理,紧紧的跟上了生产者写入Broker的消息速率,那么你每次拉取几乎都是在拉取最近刚刚写入CommitLog的数据,几乎都是在os cache里。

        但是如果Broker的负载很高,导致你拉取消息的速度很慢,或者是你自己的消费者机器拉取到一批消息之后处理的时候性能很低,处理的速度很慢,这都会导致你跟不上生产者写入的速率。

    比如人家都写入10万条数据了,结果你才拉取了2万多条数据,此时有5万多条最新的数据都是在os cache里的,有3万多条你还没拉取的数据是在磁盘里的,那么当你后续再拉取的时候,必然很大概率是从磁盘里读取早就刷入磁盘的3万多条数据。接着之前在os cache里的5万多条数据可能又被刷入磁盘了,取而代之的是更新的几万条数据在os cache里,接着你再拉取的时候,又会从磁盘里读取刷入磁盘里的5万多条数据,相当 于你每次都在从磁盘里读取数据了。

【6】Master Broker什么时候会让你从Slave Broker拉取数据?

到底什么时候Master Broker会让你从Slave Broker拉取数据?

    假设此时你的Broker里面已经写入了10万条数据,但是你仅仅拉取了2万条数据了,也就是说你还有8万条数据是没有拉取的。然后broker自己是知道机器上的整体物理内存是多大的,他也知道自己可用的最大空间占里面的比例,他是知道自己的消息最多可以在内存里放多少的。比如说他知道自己也就在内存里放5万多条消息而已。因为他知道,他最多只能利用10GB的os cache去放消息,这么多内存最多也就只能放5万多条的数据。

    然后这个时候你过来来拉取消息,发现你还有8万条消息没有拉取,这个8万条消息是大于10GB内存最多存放5万条消息的。那么此时就说明肯定有3万条消息目前是在磁盘上的,不在os cache内存里。

    所以经过上述判断,会发现此时你很大概率会从磁盘里加载3万条消息出来,这种情况下,很可能是因为自己作为master broker负载太高了,导致没法及时的把消息给你,所以你落后的进度比较多。这个时候,他就会告诉你,我这次给你从磁盘里读取了3万条消息,但是下次你还是从slave  broker去拉取吧。

    以上就是这个关键问题的解答:本质是对你当前没有拉取消息的数量和大小,以及最多可以存放在os cache内存里的消息的大小,如果你没有拉取的消息超过了最大能使用的内存的量,那么说明你后续会频繁的磁盘加载数据,此时就让你从slave broker去加载数据了。

相关文章

网友评论

      本文标题:25、消费者到底是根据什么策略从Master或Slave上拉取消

      本文链接:https://www.haomeiwen.com/subject/qqmaahtx.html