【HBZ分享】Kafka的Consumer消费者机制 与 分区策略讲解 与 Rebalance重平衡,通俗易懂

消费者根据什么模式从Broker获取数据?

Kafka集群搭建 并 整合springboot.
Kafka日志存储流程和LOG日志解析 + LEO + HW 讲解【点击这里】.
Kafka数据文件存储-可靠性保证ACK-ISR核心【点击这里】.
Kafka中日志清理策略.
Kafka高性能之零拷贝原理.

  • 消息是Broker主动push 还是 Consumer去pull的?
    答:是Consumer去pull的

  • Kafka为什么设计成Consumer去pull拉取,而不是broker主动push?

    1. pull模式可以根据消费者自身能去自行调整,比如有3个Consumer,第二个能力很强,那么处理速度就更快,Kafka默认处理完一条消息再去拉取下一条消息,所以他就会拉取更多的消息去处理,可以把自身优势发挥到最大。另两个能力偏弱,拉取就会少一些。如果通过broker去push,那么broker并不知道每个消费者的能力,就有可能使能力强的处于空闲状态,能力弱的造成消息堆积
    2. broker主动push推送优势: 可以快速处理消息,因为使主动推送,这点比Consumer有强,因为Consumer主动pull是有时间间隔的,这个时间间隔我们称之为延迟
    3. broker主动push推送劣势:由于不清楚Consumer能力,高并发场景,极有可能导致分配不均衡,使能力强的Consumer处于空闲状态,能力弱的造成消息堆积(注意:这里均衡不是指每个Consumer得到一样数量的消息,而是充分发挥每个消费者的能力,显然弱的Consumer都达到瓶颈了,强的Consumer还跟没事一样。一个倾尽自己所有能力,一个似乎还没使劲,这种情况就叫不均衡。)
    4. Consumer是如何间隔性去拉去的,如果Broker没有没有消息了会怎样?
      Consumer可以配置timeout时间,broker没有数据时,阻塞一段时间后再返回
    5. 同一条消息可以被不同消费者组的consumer同时进行消费

一个Topic分区那么多,那么消费者从哪个分区进行消费?

  • 一个topic有多个分区,每个消费者组又有多个Consumer,那是怎么分配的?
  1. 一个topic可以有很多个Consumer来消费,因为该topic中可以有很多个partition分区(leader分区)
  2. 一个partition分区里的leader,只能由消费者组中的某一个Consumer来进行消费,不同组的Consumer可以同时消费一个partition
  • Consumer是如何被分配到某个partiton分区中的消费消息?

  • round-robin(RoundRobinAssignor非默认策略) 轮询

    1. 【按照消费者组】进行轮询分配,同个消费者组监听不同主题也一样,是把所有的partition和所有consumer都列出来,不管你这些partition是来自哪个topic的。所以如果消费者组里面每个消费者订阅的topic是一样的才是理想状态,如果组内消费者订阅的主题不同,那就会造成分配不均匀问题。
      大家到这里是不是很懵圈,明明和topic没关系,为啥又牵扯到订阅topic要一样才行,下面用图+解释告诉更清楚地展示

    理想状态的round-robin分配, 即组内所有消费者监听的topic完全一致
    在这里插入图片描述
    弊端:非理想状态的分配,即组内每个消费者监听的topic都不同
    consumer1只监听topic1
    consumer2监听topic1,topic2
    consumer3监听topic1,topic2,topic3

在这里插入图片描述
造成如上不均衡分配的原因:topic1由于被所有consumer监听,所以topic1是正常的轮询平均分配给每个consumer。 topic2由于只有consumer2,consumer3监听,consumer1并没有监听topic2,所以partition4,partition5只能在consumer2,consumer3这俩之间进行轮询。而topic3只有consumer3监听,随意topic3的所有partiton全部归consumer3消费,这样会导致consumer3的压力巨大,非常不均衡。这就是round-robin策略的弊端

  • range(RangeAssignor默认策略) 范围

    1. 【按照主题topic进行分配】每个主题topic会把它里面的partiton平均分配给监听他的consumer,缺点就是如果监听topic有2个consumer, 但是topic中有5个partiton, 那么第一个consumer1会多监听一partition即监听3个。如果有大量的这种topic,那不均衡现象就会明显。如何

    在这里插入图片描述
    上图可见,一共8个分区,consumer1却监听了5个,因为range策略是按照topic来看的,所以topic之间的partition是相互独立的,即先把topic1的3个partition平均分给2个consumer,再把topic2的两个partition平均分给2个consumer,最后再把topic3的3个partiton平均分给2个consumer。所以不要看成8个partiton分给两个consumer,要以3个,2个,3个partiton的角度分别平均分配给2个consumer,这就是range的策略

Kafka的重平衡

  • 什么是Reblance操作

    1. kafka均匀的分配某个topic下所有的partition到各个消费者,从而使得消息的消费速度达到最快,这就是平衡。
    2. 而rebalance(重平衡)其实就是重新进行partition分配, 从而使得partiton的分配重新达到平衡
  • 哪些操作 或 变化能触发rebalance重平衡?

    1. 当消费者consumer数量发生变化时会触发重平衡:比如启动10消费者时,由于10个消费者不可能同时启动完成,当启动完第一个consumer时分给了该消费者20个partition,当第二个consumer启动好了的时候,就会触发重平衡,使得每个consumer监听10个partition,随着更多得consumer启动成功,会不断地重平衡,均匀得分配到各个consumer
    2. 当分区partition数量发生变化时:比如kafka的某个节点突然挂了,导致该节点的topic都不可用,从而导致大量的partition无法被消费,此时会触发重平衡。或者由于线上压力比较大,有创建了新partition进行缓解压力,此时也会触发重平衡。
  • 当consumer从宕机中恢复过来了,又是如何接着消费的呢?

    1. 消费者consumer会记录offset,当恢复后会接着从offset记录的位置开始消费
  • offset保存在哪里?又是怎么样去保存的?

    1. 旧版kafka的offset会记录在zk 和 本地, 新版的kafka默认把offset保存在内置topic中,名称是_consumer_offsets
    2. kafka是如何保存这些offset呢?
      (1). 比如该topic有50个partition(分区数量由offset.topic.num.partition来配置), 每个partition有3个副本。
      (2). 通过groupId组id的hash值 和 offset.topic.num.partition分区数量进行取模,来确定某个消费者组已消费到的offset保存到_consumer_offsets主题的哪个分区中
      (3).每个partition分区都有自己的key, value来保存这个offset,那么key = 消费者所在组名 + 主题 + 分区号, 而value就是offset的值,这样每个partition就知道自己应该去哪里找offset,然后接着消费了。
    3. 存在的问题: 该架构很明显使client-server架构,所以必然会触及到网络延迟而导致重复消费问题,所以客户端消费时需要做【幂等性校验】,消费前先检测下该消息messageId是否已经被消费过即可。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值