Kafka 面经 原理篇(二) 消费者

Kafka 面经 原理篇(二) 消费者

最近会持续更新,全文已整理在Github仓库 eat-kafka,喜欢可以收藏点赞,有问题欢迎指出

最近一次更新 2021年6月9日10:35

  • 什么是消费者组?
- 传统的“消息队列”的问题
	- 点对点模式,消息只能被下游的一个consumer消费(伸缩性差)
	- 发布 / 订阅模型,因为每个订阅者都必须要订阅主题的所有分区

- Consumer Group 是 Kafka 提供的可扩展且具有容错性的消费者机制
	- 多个消费者实例共享一个公共Group ID,组内的所有消费者协调在一起来消费订阅主题的所有分区。
	- 每个分区只能由同一个消费者组内的一个Consumer实例来消费。每个实例不要求一定要订阅主题的所有分区,它只会消费部分分区中的消息。
  • 怎么管理消费位移?
- 消费者在消费的过程中需要记录自己消费的位置信息
	- 对于 Consumer Group 而言,它是一组 KV 对,Key 是分区,V 对应 Consumer 消费该分区的最新位移。
	
- 老版本:位移保存在 ZooKeeper 中,将服务器节点做成无状态的(提高伸缩性),但ZooKeeper 不适合进行频繁的写更新

- 新版本:将位移保存在 Broker 端内部主题__consumer_offsets中
  • 什么是rebalance?
- 协议,规定了一个 Consumer Group 下的所有 Consumer 如何达成一致,来分配订阅 Topic 的每个分区
- 在 Rebalance 过程中,所有 Consumer 实例都会停止消费,等待 Rebalance 完成。类似JVM垃圾回收机制的万物静止的收集方式(stop the world)
  • 何时进行rebalance?
- 组成员数发生变更。新Consumer加入组或者离开组(或者有consumer崩溃被踢出组)

- 订阅主题数发生变更。Consumer Group可以使用正则表达式的方式订阅主题,在 Consumer Group的运行过程中,新创建了一个满足这样条件的主题

- 订阅主题的分区数发生变更
  • 怎样进行rebalance?
- 三种分配策略
	- Range:对同一个主题里面的分区按照序号进行排序。用分区数除以消费者线程数量来判断每个消费者线程消费几个分区。
	- RoundRobin
	- Sticky:0.11.X,分配要尽可能的均匀,分配尽可能的与上次分配的保持相同

- 目前 Rebalance 的设计是所有 Consumer 实例共同参与,全部重新分配所有分区。
	- 最有效的做法还是尽量减少分配方案的变动
  • Rebalance的弊端?
- 在整个rebalance的过程中,STW让所有实例都不能消费任何信息,对Consumer的TPS影响很大

- Relalance很慢,Group下的Consumer会很多

- Rebalance 效率不高,Group下的所有成员都需要参与进来,而且通常不会考虑局部性原理
  • 什么是Coordinator?
- 专门为 Consumer Group 服务,负责为 Group 执行 Rebalance 以及提供位移管理和组成员管理等
	Consumer提交位移时,其实是向Coordinator所在的Broker提交位移。
  	Consumer启动时,也是向Coordinator所在的Broker发送各种请求,然后由Coordinator负责执行消费者组的注册、成员管理记录等元数据管理操作
  
- 所有 Broker 都会创建和开启相应的Coordinator组件
  • Consumer Group 如何确定为它服务的 Coordinator 在哪台 Broker 上呢?
1 先确定由位移主题的哪个分区来保存该Group数据
	partitionId=Math.abs(groupId.hashCode() % offsetsTopicPartitionCount)
2 找出该分区Leader副本所在的Broker,该Broker即为对应的Coordinator
  • 如何避免rebalance?
- rebalance的时机
	组成员数量发生变化
	订阅主题数量发生变化 (运维主动操作)
	订阅主题的分区数发生变化 (运维主动操作)

- 组成员数量发生变化
	- 未能及时发送心跳,导致 Consumer 被“踢出”Group 而引发的
		让其至少能够发送至少 3 轮的心跳请求
		session.timeout.ms=6s
		heartbeat.interval.ms = 2s

	- Consumer 消费时间过长导致的
		- 如果在每次拉取消息之后需要对消息做一定的处理
			需要把max.poll.interval.ms设置的稍微大一些,预估一下处理消息的最长时间,给业务留下必要的时间(Consumer消费能力过低或者一次性拉取数据过多)
		- 排查一下Consumer端的GC表现,比如是否因为频繁的Full GC导致Consumer长时间的停顿,而引发非预期的Rebalance
  • 如何得知broker rebalance过多?
- Coordinator所在的broker日志,如果经常发生rebalance,会有类似于"(Re)join group" 之类的日志
  • 什么是位移主题(__consumer_offsets)?
- 老版本:保存在ZooKeeper中,减少Broker的状态信息,高伸缩性,但ZooKeeper 并不适用于这种高频的写操作

- 新版本:将位移数据作为一条条普通的 Kafka 消息,提交到 __consumer_offsets 中,刚好Kafka自身能够实现高持久性和高频的写操作

	- 为什么不用HashMap存一次然后替换值就行? 保证顺序IO,高吞吐
  • 什么是位移主题有哪些信息?
- 消息格式是Kafka自定义的,用户不能随意修改

- 三类消息
	保存位移的消息:  key = <Group ID,主题名,分区号>  value = 位移 & 位移相关的元数据
	保存Consumer Group信息的消息,用来注册Consumer Group
	删除Group过期位移、删除Group的消息
  • 什么时候创建位移主题?
- 当 Kafka 集群中的第一个 Consumer 程序启动时,就会会自动创建位移主题
	- 分区数:Broker 端参数 offsets.topic.num.partitions,通常来说,同一个group下的所有消费者提交的位移数据保存在同一个分区中
	- 副本数:offsets.topic.replication.factor

- 也可以在Kafka集群尚未启动任何Consumer之前手动创建
  • 什么时候向位移主题写入位移信息呢?
- 自动提交位移:只要Consumer一直启动,就会无限期地向位移主题写入信息,这就需要重复消息删除策略
	enable.auto.commit = true
	auto.commit.interval.ms

- 手动提交位移
	enable.auto.commit = false
  • 怎样删除位移主题中的过期消息?
- Compaction(整理机制):
	对于同一个 Key 的两条消息 M1 和 M2,如果 M1 的发送时间早于 M2,那么 M1 就是过期消息。
	Compact 的过程就是扫描日志的所有消息,剔除那些过期的消息,然后把剩下的消息整理在一起。

- 专门的后台线程Log Clean定期地巡检待Compact的主题
  	如果位移主题无限膨胀占用很多磁盘空间,很有可能就是这个线程挂了

最近会持续更新,全文已整理在Github仓库 eat-kafka,喜欢可以收藏点赞,有问题欢迎指出

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值