kafka---为什么kafka中1个partition只能被同组的一个consumer消费?


 

Kafka中每一个客户端的offset是由自己进行维护的,kafka并没有对同一个消费组中每个消费者的offset做中心化处理,所以如果他们消费同一个partition 都分别用自己的offset 会出现重复消费的问题。

offset是什么?

offset

partition中的每条消息都被标记了一个序号,每个序号都是连续的,这个序号表示消息在partition中的偏移量,称为offset,每一条消息在partition都有唯一的offset。

offset从语义上来看有两种:Current offset 和 committed offset

Current offset

  • Cuttent offset 保存在客户端中由客户端自己维护,它表示消费者希望收到下一条消息的序号,它仅仅在poll()方法中使用,例如:消费者第一次调用poll()方法收到了20条消息,那么 cuttent offset的值将被设置成20 下一次poll时,kafka就知道要从序号为21的消息开始读取,这样能保证消费者每次poll消息时,收到的消息不重复

Committed offset

  • Committed Offset保存在Broker上 (V0.9之后的版本),它表示Consumer已经确认消费过的消息的序号。主要通过commitSync()来操作。举例:Consumer通过poll()方法收到20条消息后,此时Current Offset就是20,经过一系列的逻辑处理后,并没有调用commitSync()来提交
  • Committed Offset,那么此时Committed Offset依旧是0。
  • Committed Offset主要用于Consumer Rebalance(再平衡)。在Consumer Rebalance的过程中,一个Partition被分配给了一个Consumer,那么这个Consumer该从什么位置开始消费消息呢?答案就是Committed Offset。另外,如果一个Consumer消费了5条消息.(poll并且成功commitSync)之后宕机了,重新启动之后,它仍然能够从第6条消息开始消费,因为Committed Offset已经被Kafka记录为5。
  • Committed Offset是为了每一个消费组进行记录的 不同的消费者组分别记录

小结:

Current offset 是针对消费者 poll过程为了保证每次poll都返回不重复的消息

Committed offset 是为了 Consumer Rebalance(再平衡) 的你过程,它能够保证同一个消费者组中新的消费者在正确的位置开始消费,避免重复消费。

同一消费组内多个消费者同时消费会出现重复消费。例如A1 1-10 POS 10

A2 10-20 POS 20

下次消费的时候 A1是 11-20重复消费

解决方案

  • 假设broker对index进行维护。但是consumer 是进行pull操作的,拉取操作一般来说都是由拉取方提供index,数据方根据index 返回数据。如果由数据方维护index,会增加获取index 的通信开销。
  • 假设consumer端进行多人的index维护,那么就得引入中心的概念,大家都在中心去获得当前的index,这会增加复杂性。
  • 在consumer端维护单人index,可以方便的pull数据。牺牲了分区的分布式消费。由于可以有多个分区,权衡之下是较为合理的方案。


 

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

这代码有点上头

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值