08|消费端:消费者客户端的SDK有哪些设计要点?(上)
消费模型的选择
Pull 模型
- 深入了解
- 翻译
- 解释
- 总结
本文介绍了消费端SDK设计的要点,主要包括消费模型的选择和分区消费模式设计。在消费模型的选择方面,文章介绍了Pull、Push和Pop三种消费模型。Pull模型适用于处理速度不敏感的场景,但可能出现大量无效返回的调用;Push模型为了解决消费及时性而提出,可以通过Broker内置Push功能、Broker外独立实现Push功能的组件或在客户端实现伪Push功能来实现;Pop模型简化了消费模型,将分区分配的工作移到了服务端。分区消费模式的设计包括独占消费、共享消费、广播消费、灾备消费四种思路。独占消费保证分区维度的消费是有序的,共享消费避免单个消费者的性能和稳定性问题导致分区的数据堆积,广播消费一条数据能够被多个消费者消费到,灾备消费在保持独占消费的基础上加入灾备的消费者。总的来说,消费端SDK的设计需要根据具体业务需求选择合适的消费模型,并结合分区消费模式设计,以提高消费性能和及时性。
《深入拆解消息队列 47 讲》,新⼈⾸单¥59
全部留言(14)
- 最新
- 精选
- 文敦复文中的“因为 Push 模型需要先分配分区和消费者的关系,客户端就需要感知分区分配、分区均衡等操作,从而在客户端就需要实现比较重的逻辑。” 这里的Push模型指的提到的第三种“伪Push模式”吧?
作者回复: 是的,这里指的是pull模型下需要用到消费分组的情况。伪push的底层实现也是pull,所以是指第三种“伪Push模式”
2023-07-07归属地:四川2 - 文敦复文中提到“实现广播消费一般有内核实现广播消费的模型、使用不同的消费分组消费和指定分区消费三种技术思路。”关于最后一种广播消息指定分区进行消费没搞清楚:为什么指定分区消费可以做到广播消费的效果?1个Topic会分成多个分区,所有分区合起来才的整体才是的所有消息?如果客户端指定分区消费不就只能消费其中一部分吗?
作者回复: 我理解的广播消费的效果是: 一条消息可以被多个消费者消费到。 就像,你把一条消息广播发给多个消费者。此时: 1. 如果只有一个分区,那么所有消费者都消费这个分区,就能达到这个效果。 2. 如果一个topic有多个分区,那么所有消费者都指定消费所有分区,也能达到这个效果。 我理解,我们的gap点在于,你认为一个消费者同时只能消费一个分区,其实一个消费者可以同时指定消费多个分区的,代码上实现也不复杂。 此时就能达到这个效果了。
2023-07-07归属地:四川22 - 张申傲思考题:当 Topic 的消息写入存在倾斜,某些分区消息堆积很多,此时可以选择【共享消费】模式,给该 Partition 下挂多个 Consumer 来提升消费吞吐量,快速处理掉积压的消息。 小建议:这里【共享消费】这个说法个人感觉有点歧义,容易和【广播消费】产生混淆,是不是叫做【负载均衡消费】更直观一点?
作者回复: 这一点我个人的思路是这样子的,你参考下哈。 关于这种一个分区的消息可以投递给多个消费者。pulsar 叫做共享订阅,rocketmq叫做消息粒度负载均衡。 从个人来看,共享消费/共享订阅看起来比较直观能理解到意思,负载均衡消费的概念有点大。所以我将它叫做共享消费是这个思路。
2023-07-07归属地:北京1 - 虚竹老师好,关于共享消费模型,或者叫消息粒度负载均衡,假设一个消费者组有 a b c 共3个具体消费者,假设b未返回消费状态,a c是不受影响可以继续往后消费吗? 这样的话,该消费者组到底消费到队列的哪个位置了是不是就有点乱了?这个问题是怎么解决的呢?
作者回复: 在我看来,这是一个技术实现的问题。 默认情况下,我们理解的都是顺序消费的模型,用Offset 来记录消费的最新位置,此时只会记录消费的最新位点。 但是如果是这种共享消费模型或者叫消息粒度负载均衡。那么代码实现的机制就不一样了,不能再继续使用一个Offset 来表示消费进度。就得换一种方式。 来说一种简单的思路,比如可以增加ack机制,在内存或文件中单独记录哪些消息被消费了,但是没有ack。然后做对应的检测和后续的处理。 具体代码实现方案会有很多,主要考虑的还是内存占用和读写的性能。可以参考一下rocketmq和pulsar的实现。因为篇幅原因,就不展开,需要的话,加微信群讨论更多细节。
2023-10-10归属地:北京2 - Geek4329“Pop 模型本质上是 Pull 模型的一种,只是在实现和功能层面上,与 Push 的实现思路和适用场景不一样。”这句话怎么理解呢?前半句讲pop跟pull的关系,后半句又讲pop跟push的关系
作者回复: 不好意思,这里写错了,应该是: 与 Pull 的实现思路和适用场景不一样。 所以整句话是:“Pop 模型本质上是 Pull 模型的一种,只是在实现和功能层面上,与 Pull 的实现思路和适用场景不一样。”
2023-10-09归属地:北京 - jackfan独占是一个分区只能给一个消费者,共享是一个分区的消息给多个消费者,并且一条消息不会给多个消费者,广播是一个消费会被多个消费者消费,灾备也是独占消费。所以这里需要选择共享消费
作者回复: 是的,没错,理解很到位呢~
2023-07-13归属地:上海 - Johar共享消费模型可以解决分区消息堆积问题
作者回复: 是的,但是就无法保证顺序性了,使用的时候需要考虑到这个点。
2023-07-07归属地:重庆 - cykuo先回答问题:pop模型却可以根据积压情况动态调整消费分区,一定程度上可以解决写入倾斜问题。
作者回复: 是的,因为是在Broker处理的消息分配投递的逻辑,Broker能感知到消息堆积的情况,可以灵活的去投递。所以在一定程度上可以解决数据倾斜的问题。
2023-07-07归属地:北京 - justxhkpulsar 的 Key_Shared模式。多个消费者,可以保证单个key发送给同一个消费者,保证局部有序。2023-07-11归属地:广东1
- shan1. Pull模型 客户端不断轮询的方式向服务端拉取消息。优点是客户端可以根据自身处理速度区拉取数据,缺点没有消息消费时,可能会出现大量无效的调用。 2. Push模型 指服务端有数据时会主动推送给客户端,一般有Broker内置Push功能、Broker独立实现Push组件、客户端实现伪Push功能。 (1)内置Push功能 在Broker中内置标准的Push功能,服务端想客户端主动推送数据。优点是自带推送功能,不需要重复开发和部署,缺点是消费者很多时,维护较多长链接,引起Broker性能和稳定性。 (2)独立实现Push组件 独立于Broker提供一个专门实现推送功能的组件。优点是独立部署,解决了Broker的性能问题,缺点是本质还是需要从服务端Pull数据再Push给客户端,并且独立部署开发运维成本高。 (3)客户端实现伪Push 客户端内部,底层通过Pull模型先从服务端拉取数据,在通过回调的方式触发回调函数推送消息进行消费,这种方案依旧是Pull模型,需要不断轮询向服务器请求数据。 RocketMQ在5.0之前有Pull和Push两种方式(客户端实现伪Push),对于Pull模式,消费者需要不断向Broker发送拉取消息的请求,拉取消息后会将消息放入一个阻塞队列中,主线程开启循环不断从这个阻塞队列中获取拉取到的消息进行消费。 对于Push模式,本质依旧就是通过Pull的方式拉取数据,只不过不需要开启循环不断从队列中读取数据,而且拉取到消息之后,会触发回调函数进行消息消费,从表面上看就像是Broker主动推送给消费者一样,所以是伪Push。 不管Push模式还是Pull模式,RocketMQ都需要在消费者端进行负载均衡,为消费者分配对应的消息队列,之后才可以向Broker发送请求从队列中拉取消息。 3. Pop模型 Push模型需要在消费者端做负载均衡分配分区/消息队列,如果负载均衡时间过长会影响消费者消费,为了解决这个问题,推出了Pop模型,不再将分区/消息队列与消费者绑定,消费者只需按Pop模型提供的接口去获取消息内容即可,不再感知数据的分布情况。 RocketMQ 5.0的Pop模型,消费者不需要再进行负载均衡,MessageQueue也不与消费者绑定,消费者只需调用服务端提供的接口获取消息进行消费并确认即可,并且Pop模型可以实现消息粒度的分配,在5.0之前只能基于消息队列进行分配。2023-09-23归属地:美国1