深入拆解消息队列 47 讲
许文强
前腾讯云 Kafka 技术负责人
5385 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 50 讲
深入拆解消息队列 47 讲
15
15
1.0x
00:00/00:00
登录|注册

08|消费端:消费者客户端的SDK有哪些设计要点?(上)

你好,我是文强。上节课我们讲了生产端,这节课我们来讲讲消费端。
从技术上看,消费端 SDK 和生产端 SDK 一样,主要包括客户端基础功能和消费相关功能两部分。客户端基础功能在上一节讲过,我们就不再重复。
从实现来看,消费相关功能包括消费模型分区消费模式消费分组(订阅)消费确认消费失败处理五个部分。内容比较多,所以本节课我们将会聚焦消费模型的选择和分区消费模式设计这两个部分,下节课会继续完成剩下三个部分的讲解。

消费模型的选择

为了满足不同场景的业务需求,从实现机制上来看,主流消息队列一般支持 Pull、Push、Pop 三种消费模型。

Pull 模型

Pull(拉)模型是指客户端通过不断轮询的方式向服务端拉取数据。它是消息队列中使用最广泛和最基本的模型,主流的消息队列都支持这个模型。
它的好处是客户端根据自身的处理速度去拉取数据,不会对客户端和服务端造成额外的风险和负载压力。缺点是可能会出现大量无效返回的 Pull 调用,另外消费及时性不够,无法满足一些需要全链路低耗时的场景。
为了提高消费性能,Pull 模型都会支持批量读,即在客户端指定需要拉取多少条数据或者拉取多大的数据,然后传递给服务端。客户端拉取到数据并处理完成后,再重复拉取数据处理。如前面讲的,这种拉取模式的缺点是可能会出现长时间轮询到空数据的情况,从而浪费通信资源,提高服务端的负载。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

本文介绍了消费端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归属地:四川
    2
    2
  • 张申傲
    思考题:当 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归属地:北京
  • justxhk
    pulsar 的 Key_Shared模式。多个消费者,可以保证单个key发送给同一个消费者,保证局部有序。
    2023-07-11归属地:广东
    1
  • shan
    1. 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
收起评论
显示
设置
留言
14
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部