kafka某个topic的单个分片为什么只能被一个消费者组内一个消费者消费?

文章解释了Kafka中分片如何确保在一个消费者组内,消息不被重复消费,避免了currentOffset可能导致的并发问题和commitOffset的网络开销及潜在数据一致性风险。
摘要由CSDN通过智能技术生成

kafka某个topic的单个分片为什么只能被一个消费者组内一个消费者消费?

一、概要

  • 很多文章只阐述了kafka的分片与消费者组内的消费者为 多对一的关系,并没有说清楚为什么一个分片为什么只能被组内一个消费者消费者,这里讲讲我对这个问题的理解。

二、知识储备

  1. 当kafka的topic被消费者组订阅时,那么kafka与组内的消费者之间应该构成点对点模式
  2. 当kafka的topic被多个消费组订阅时,那么kafka与不同组的消费者之间构成发布订阅模式
  3. kafka使用offset维护消息的消费,存在两种offset:currentOffset 、commitOffset。
  4. currentOffset由消费者客户端自身维护,消费者每次会根据currentOffset拉取消息,例如某次收到10条消息,那么currentOffset就会设置成10,下次poll消息时就会从11号的数据开始拉取,保证不会重复消费。currentOffset的格式为:topic + partition (currentOffset的存储格式可能不太准确,没有找到权威性的资料)
  5. commitOffset由kafka服务端维护,消费者poll消息时如果提交currentOffset,那么commitOffset就会进行同步。kafka不会单独为某个消费者设置commitOffset,commitOffset的格式为:topic + partition + groupId。

二、问题分析

1. 分片为什么只能被一个组内消费者消费

  • 其实这是一个设计上的问题。当kafka的topic被消费者组订阅时,那么kafka与组内的消费者之间应该构成点对点模式。在这在情况下,一条message是不允许被组内消费者重复消费的。
  • 我们假设现在一个分片被两个组内消费者A和B消费,那么为了保证一条message不被A和B重复消费了,kafka就不能让A和B使用currentOffset的方式来读取数据,而是需要让A和B使用一个共同的offset。这时候有人会想,使用commitOffset不就行了吗? 事实上的确可行,但是我认为这样会有以下几种问题:
  1. commitOffset是存储在kafka 的,那么消费者poll消息时就必须先获取到这个commitOffset,增加了一次网络开销。
  2. 涉及到了多个线程对同一个offset(临界区,共享数据)进行操作,kafka还必须得维护一套处理并发的机制来保护commitOffset线程安全。
  3. 如果kafka宕机或者出现异常导致commitOffset丢失,那么所有消费这个分片的消费者会丢失消费进度。
  • 基于以上原因,所以分片只能被一个组内消费者消费
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值