开发者学堂课程【消息队列 RocketMQ 5.0 云原生架构升级课程:RocketMQ 5.0客户端负载均衡机制】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/1234/detail/18401
RocketMQ5.0 客户端负载均衡机制
内容介绍
一、课前介绍
二、负载均衡的意义与原理
三、负载均衡操作流程
四、负载均衡对消费的影响
五、最佳实践建议
六、消息级负载均衡介绍
一、课前介绍
内容是要看客户客户端负载均衡,其实在开始的课程之前,首先来介绍一下本次课程的内容,本次课程主要介绍要看所有的负载变动机制,涉及负载均衡的意义,发生的时机,它的原理解析消费的一些影响,最后给出一些最佳实践,以及介绍一下 Rocket MQ5.0中最新推出的消息级别的均衡机制。
二、负载均衡的意义与原理
首先第一个部分是介绍负载均衡的意义,要介绍负载均衡,就首先Rocket MQ的效益储存的模型,在Rocket MQ的模型中,消息是按照队列的方式分区设计储存的,让Rocket MQ的队列模型使得生产者消费者还有它的这个读写队列时间,都是一些多多的映射关系,他们彼此之间可以无限的水平扩展,这个相于一些传统的消息队列是一个很大的优势,尤其是在流式处理的场景下,能够保证同一队列的消息被相同的消费者处理,于批量处理愈合处理更友好。
然后来看一下,针于这样的一个队列模型,消费者是如何消费的消息的。消费者在启动的时是需要指定他订阅的topic和它的订阅语句是什么,他消费一个topic中的消息,其实也就等同于消费这个 topic上所有队列的消息。
就如上图所示,粉丝们a一是消费队列一中的消息,m一到m三,配送a二,收费队列二三中的消息,所以要保证每个消费者的负载尽可能均衡,其实也就是保证每个消费者消费的队列数量尽可能的一致。并且在异常情况下,比如说客户端档期,队列可以在不同的消费者之间进行一个迁移。
然后再来看一下负债均衡的原理,负载均衡其实是一个客户端和服务端互相配合一个协调的过程,先综合服务端和客户端的各自的职责回答这样一个问题,就是何时会发生负债均衡,
首先来看一下这个上面这个图,它是客户端的一个类的结构。创建一个push consumer的时候,他会去创建底层的资源,比如说这里面的MQclientInstance,这个类负责和服务端的一些交互以及底层的一些协调。比如负载均衡是就是他创建的与plus service这个服务来进行执行的,这个服务会在启动时立即进行一次负载均衡,然后每20秒做一个定时任务,执行一次负债均衡的操作。
三、负载均衡操作流程
(1)负载均衡核心内容
然后来看一下每次负载均衡的时候,他究竟是做了什么。可能这里面最核心的一个类,就把代码贴在上面了,这里面有点缩略,把最核心的一些方法列出来了。首先是大家获取到他订阅的所有topic的所有队列,然后再获取他所在的group里面所有在线的消费者,并把这二个作为一个排序。然后根据配置的这个负载均衡策略,在本地计算出自己要负责的面,计算书要负责队列之后,再每一个队列来进行获取位点,拿取消息投递消费这样的操作。这里面很关键的一点是客户端的负载均衡实际上是一个本地执行的过程,并没有一个分布式的协调,所以这就要求同一个消费组里面的所有的消费者,它的配置都是一样的,这个配置包括负载系统的策略,也包括它的订阅关系。
(2)配置不一致的情况讲解
如果你的配置不一致,它会发生什么样的情况。好,接下来看一下服务端的一个通知负载均衡的机制,服务端通知负载均衡,实际上也就是调用客户端的负载均衡接口。它的调度链路是怎么样的,它分两种情况,首先是客户端上下线的时候就调用这个方法,上线就是新的客户端启动时,会发送心跳到服务端,下线的时候,客户端调用丧葬方法来进行一个优先下线,也会发送下线的请求,就是反注册的需求到服务端。
第二种是客户端和服务端的底层连接发生了异常,比如服务端牵涉到nice channel的一些事件,比如说idol flows或者exemption,他也会强制的断开连接,并且通知同组的其他客户端来进行一个附带性的操作。那第二种情况是订阅关系变化,比如说某一个group新订阅的topic或者是旧的topic不代表订阅,也会触发这个 Google下面所有的消费者进行一个负债均衡。接下来看一下负载均衡的策略都有哪些种,
前面已经介绍了负载均衡实际是变更消费者所处理的这个队列的数量,所以这里面的负载均衡策略就消费者整负载均衡的结果,或者是它的收敛速度决定性的一个影响。
(3)负载均衡策略
这里首先看一下比较常见的几种负载均衡策略,第一个是默认的平均分配策略,如图所示这里面有4个客户端,12个队列。初始情况下,每个客户端都平均的分配了三个队列,然后此时客户端二下线了,也就是他之前分配到了456这三个队列,被释放掉了。其中队列4被重新分配这个附带一,队列五六被分配给了客端三,此时客户端三的接数量就明显多于客户端一个客户端4,所以说它的队列9被重新分配给了客户端4。
再来看一下它最终的覆盖纠纷的结果。3个客户端每个客户端各持有4个队列。那再来看一下它的收敛速度,他一共变更了4个队列,然后来第二种附带学科策略,哈希分配策略来做一个对比。基于哈希负载均衡策略,每次负载均衡时会重新分配尽可能少的队列数量,但是它会出现一个负载不均的情况。同样也是4个消费者,每个消费者分配3个队列,然后客户端二下线,来看一下它持有的队列456这样子,这次分配的策略是怎么样的,可以看到队列次被重新分配给了后端一,5,6,被分配给了客户端单,最终每个客户端持有的数量是持有的队列数量是这样的,客户端一是有4个客户端3是有5个。
客户端四持有三个,比如说它的负载是有些微的布局,但是它的收敛速度是比较快的,只重新分配了三个队列,之前的平均分配的这个策略是平均分配的4个队列,也就是说于客户端数量比较少,或者说队列数量比较少的情况,其实更适合于平均分配的策略,因为它分配的更均衡,而客户端数量比较多,或者的队列数量比较多的时候,为了避免每一次发布影响太多的正常消费的客户端,更推荐哈希的这种分类策略,它的修改速度要更快一些。
四、负载均衡对消费的影响
具体分析一下负载均衡的选择消费的有哪些影响,这里以一个真实的线上场景来做举例,下图中是一个交易收发的GPS附图,其中绿色的曲线代表着发送GPS,黄色的曲线代表消费GPS。
很容易就发现在二十一点五十分左右出现了一个消费的模式,有一个突发的尖峰,这两个时间点是在进行应用发布。根据发文的分析,其实某个消费者下线的时候,同组的其他消费者是要去获取到他所持有的这些队列来重新进行消费的,而感知这一变化是需要一定的时间的,所以会有秒级的这种消费延迟的产生。在发布结束之后,消费者为快速处理堆积的消息,所以说就会看到一个先凹再突的这么一个曲线之前发布的时候,消费者的初期会带来消费速度就下降到消费结束之后,当应用发布结束之后,会有一个快速处理堆积消息的过程,就会发现消费速度有一个明显的上涨。就是这个例子就展示了应用下线是由于负载均衡带来了短暂的处理的延迟,现在消费者会从服务端获取消费的位点,继续之前的这种消费进度,如果消费者异常档期或者没有调用放档方法来进行下线,就不会去服务端上传自己的最新位点,这样的话就会使得新分配的消费者重复的进行消费。
所以这里总结一下四大均衡消费者零部件主要体现在两个方面,当一个客户端触发负载均衡的时候,第一种情况,把新配新分配的队列可能会造成同步消费,这也是官方要求做好密档的一个原因。第二种情况是于他不在乎的嘴脸,可能会出现短时间的消费停止。如果原本的消费TPS就很高,或者正好出现了一个生产的高峰,这时就会造成如图所示的这种消费毛刺。
五、最佳实践建议
最佳实践,如何来减少或者说避免这种负载均衡消费的影响,给出的第一个建议是为了避免频繁的生产线,因为应用的上下线就会带来同一个消费组里面附带数量的变化,就会触发若干次的负载均衡。后来所以为了避免负载均衡的影响,就应该尽量减少客户端上下线这种情况的出现,同时也要做好消费力的而且在应用重启或者下线之前,是要调用方法来进行一个下线。这样服务端在收到客户端下线请求后,会及时通知同组的其他客户端来触发这个费用的操作,来减少消费的延时。
第二点是要选择合适的这种负载监控策略,负载均衡的策略是要根据业务的需要来进行一个选择。比如你的业务需要保证客户端的负载均衡,尽可能的尽可能的均衡,就要选择平均分配的策略。如果你的客户端的队列数量或者是消费者数量非常的多,你为了降低应用的重启带来的消费延迟,就应该选择一致性希的。第三个建议是要保持订阅的一致,然后看客户的负载均衡是每个客户端在本地进行独立的计算,所以也务必要保证每个客户端的负载均衡算法和订阅语句都是一致的,否则附带均衡策略的不一致,会导致多个客户端分配到相同的联,此时就会造成消费的重复,或者是有些客户单分配不到这边,此时就会导致消费消息没有被消费定语句不一致,也会导致这种消息未能被消费的情况。
最后来介绍一下5.0中最新推出的消息级别和两地方的这样一个机制。消息级别的这种负载均衡的机制是为了彻底解决客户端负载均衡导致的重复消费和消费延迟的问题才推出的,同一个队列的消息可以由多个消费者来进行消费,而由服务端来保证在消息级别的这个负载均衡的时候,不会出现消息的重复或者是遗漏。也就是说消息级别的负载均衡是服务端的负载均衡机制,服务端实现了基于内部的单条消息确认,一在消费者获取到某条消息后,服务端会这样该休息枷锁,保证这条消息其他消费者不可见,直到该消息成功消费或者消费潮时,所以即使多个消费者同时消费同一队的消息,服务端也可以保证消息不被多个消费者重复的消费到,但是这也会带来新的问题,在4.0的客户端中顺利消费是一个很容易实现的一个消费意义。
六、消息级负载均衡介绍
因为数据消费的实现强依赖于队列的分配,只要某个消费者固定分配到某个队列,就可以顺利消费这个队列上的消息来实现这样一个顺序的意义,而在5.0中,消息维度的负载均衡,而在5.0中,消息维度的负载均衡的基础上,实现了顺序消费的意义,不同的消费者处理同一个消费组内的消息时,会严格按照赛后顺序锁定消息的状态,确保同一消费者的消息是串行消费的。
就如上图所示,队列中有4条虚拟消息,这4条数据虚拟消息是属于同一个消费组之一的,他们按照m1到m4的顺序来储存的,所以预期也会按照m1到m4的顺序来消费这4条消息,可以看到前面的要写m一,m二给消费者,获取到了,所以只用a一消费者的消息的状态没有提交,消费者a二是无法获取到后面的m3,m4是两条消息的,必须等到m一m二的状态提交之后,才能继续消费后面的内容,这个是要概括说5.0,分析比较自然均衡,顺序意义的一个知识。