Fork me on Gitee

RocketMQ消息堆积问题

RocketMQ消息堆积问题

RocketMQ消息堆积主要分为三个层次的问题:
其一是Producer生产速率过快,什么场景呢,比如Producer故障,比如DOS攻击,比如业务高峰(超过企业预估的,例如12306订票,双十一下单,这些一开始的时候都有超过预期的情况)。

其二是Broker消息堆积,比如Broker的性能瓶颈,Broker同步策略导致消息堆积等

其三是Consumer本身已经拉取消息的堆积。consumer消息拉取超过一定量之后会暂停消息拉取,一方面是消费者本身消费能力的现在,另一方面是由于消费端过多的消息容易造成GC频繁。

一般情况下我们都可以通过限流扩容来达到快速处理堆积的消息的目标。

消息堆积的处理策略整体上说就是生产者producer限流RocketMQ扩容消费者consumer扩容,具体要根据监控指标来判断。

熟悉了消息堆积场景,我们还需要明确消息堆积的诊断,常用的工具包括producer发送速率监控,producer服务器性能监控(网络、CPU、内存等),broker性能监控(网络、CPU、内存,磁盘使用率,GC等),消费端消费速率,消费端consumer服务器性能监控(网络、CPU、内存、数据库、GC等)

MQ消息积压

这种时候只能操作临时扩容,以更快的速度去消费数据了。具体操作步骤和思路如下:

①先修复consumer的问题,确保其恢复消费速度,然后将现有consumer都停掉。

临时建立好原先10倍或者20倍的queue数量(新建一个topic,partition是原来的10倍)。

然后写一个临时分发消息的consumer程序,这个程序部署上去消费积压的消息,消费之后不做耗时处理,直接均匀轮询写入临时建好分10数量的queue里面

④紧接着征用10倍的机器来部署consumer,每一批consumer消费一个临时queue的消息

⑤这种做法相当于临时将queue资源和consumer资源扩大10倍,以正常速度的10倍来消费消息。

⑥等快速消费完了之后,恢复原来的部署架构,重新用原来的consumer机器来消费消息。

知识点

Topic和Partition

Topic是一个逻辑上的概念,可以看成是一类消息的聚合。从物理上来说,一个Topic是由分散在各个服务节点上的Partition组成的,每个Topic可以有多个Producer向他发送消息,也可以有多个Consumer消费其中的消息。

如图所示,一个Topic是由分散在多台broker上的Pratition组成的,多台Produer按照一定的算法把消息发送给各个Partition上,consumer按照一定的算法去消费不同pratition上的消息。

每一个Pratition最大允许一个consumer去消费,一个consumer可以消费多个Pratition。

对于每一个Partition而言,每一个新增的消息都会分配一个offset,他是该消息在此分区中的唯一标准。kafka通过offset来维护消息顺序,对于同一个分区而言,消息是有序的。

这里需要重点说明一点的是,当消费速度小于生产速度的时候,仅增加消费者是没有用处的,因为多个消费者在同一个分区上实际是单线程资源竞争关系(当然还有一些冒险的单队列多消费者并行方式就是:消费者接到消息就ack成功再去处理业务逻辑,这样你就要承受消息丢失的代价),我们需要同时增加Broker上的分区数量才能解决这一问题。

参考资料

posted @ 2021-07-09 12:11  明叶师兄。  阅读(2291)  评论(0编辑  收藏  举报