Kafka工作流程-高级消费者和低级消费者
1. Kafka 高级消费者
高阶消费者是一把双刃剑,一方面简化了编程,一方面也由于编程者参与的功能过少, 可控内容过少而造成很多问题。
(1) 自动负载均衡
高阶消费者为了简化编程,封装了一系列 API,这套 API 会均匀地将分区分配给消费者 线程,消费者消费哪个分区不由消费者决定,而是由高阶 API 决定,如果有消费者线程挂 掉了,高阶 API 会检测到,进而进行重新分配。高阶消费者 API 将大部分功能已经实现, 因此,编程者编写高阶消费者的难度也随之降低,不需要关注分区的分配,只需要读取数据 就好了。
高阶消费者 API 下,固定分区个数时如果消费者个数大于分区个数,那么将会有消费 者空转,造成资源的浪费。
|
如图 2-7 所示,在高级消费者的作用下,同一个 topic 的 8 个分区均匀的分布到了 3 个 broker 上。有两个消费者组,它们互不相干,对于每个 partition 每个消费者组维护着自己的 offset,不同的消费者组可以同时消费同一个 partition。高级消费者 API 将每个 partition 均匀 地分配到了每个消费者组的每个消费者上,push-group 是两个消费者,每个消费者消费 4 个, token-group 是四个消费者,每个消费者消费 2 个。
于此同时,高阶消费者 API 为用户提供了一个高可用机制,在不同机器运行相同消费 组时,如果有机器宕机,高阶消费者 API 会检测到,然后将宕机的机器所消费的分区重新 分配给其他机器上的消费组的消费者,不会影响业务系统。
|
如图 2-8 所示,同一套程序在两台机器上同时跑,均为 group001,那么高级消费者将会 将两台机器中的 group001 视为同一个组,进而将两个 broker 的 6 个分区均匀分配到 group001 的 6 个线程中。也就是说,高级消费者关注组名,即使是不同机器上的相同组名的消费者, 也全部视为一个组的所有消费者。
|
如图 2-9 所示,当有一台机器宕机或者消费者进程挂掉时,会进行 rebalance,即重新进 行负载均衡,此时 group001 有 3 个消费者,因此高级消费者会将 6 个分区均匀分配给 3 个 消费者,每个消费者 2 个分区。
通过以上的部署实现了 Kafka 的高可用。
|
当第一台机器有 3 个消费者,而第二台机器有 4 个消费者时,由于每个 partition 只能被 一个分组内的一个消费者同时消费,因此,消费者 c4 线程空闲,拿不到数据,这就意味着, 在分区不变的情况下,增加消费者线程不能提高并发度。
问题一:Kafka 高级消费者怎样才能达到最大吞吐量?
答:分区数量与线程数量一致。
问题二:消费者消费能力不足时,如果提高并发?
答:1. 增加分区个数;
2. 增加消费者线程数;
3.自动提交 offset
在高阶消费者中,Offset 采用自动提交的方式。
自动提交时,假设 1s 提交一次 offset 的更新,设当前 offset=10,当消费者消费了 0.5s 的数据,offset 移动了 15,由于提交间隔为 1s,因此这一 offset 的更新并不会被提交,这时 候我们写的消费者挂掉,重启后,消费者会去 ZooKeeper 上获取读取位置,获取到的 offset 仍为 10,它就会重复消费,这就是一个典型的重复消费问题。
高阶消费者存在一个弊端,即消费者消费到哪里由高阶消费者 API 进行提交,提交到 ZooKeeper,消费者线程不参与 offset 更新的过程,这就会造成数据丢失(消费者读取完成, 高级消费者 API 的 offset 已经提交,但是还没有处理完成 Spark Streaming 挂掉,此时 offset 已经更新,无法再消费之前丢失的数据),还有可能造成数据重复读取(消费者读取完成, 高级消费者 API 的 offset 还没有提交,读取数据已经处理完成后 Spark Streaming 挂掉,此时 offset 还没有更新,重启后会再次消费之前处理完成的数据)。
2.Kafka 低级消费者
对于低阶消费者就不再有分区到消费者之间的 API 中间层了,由消费者直接找到分区进行消费,即消费者通过 ZooKeeper 找到指定分区的 Leader 在哪个 broker 上。
首先,在 ZooKeeper 中能够找到 Kafka 所有 topic 的分区列表,并且可以找到指定分区的 Leader 在哪个 broker 上。
|
消费者消费一条消息后,可以选择提交或者不提交,offset 可以缓存在 Redis 中,也可以自己存到 ZooKeeper 上。
当正在读取的分区挂掉了,此时读取会出现异常,由于 Kafka 存在副本机制,需要从ZooKeeper 重新获取元数据,更新列表,从而继续消费分区数据。