深入理解Kafka Consumer内部机制

肖钟城
  • 大数据技术栈
  • Kafka
大约 5 分钟

深入理解Kafka Consumer内部机制

本文为深入理解kafka producer/consumer系列文章,前面我们讲到《深入理解Kafka producer内部机制》,本片则从Consumer角度深入理解Kafka Consumer内部机制。

Kafka Consumer 是一个从 Kafka 消费消息的客户端。

基本组件:

Consumer Metadata(消费者元数据)——管理消费者需要的元数据:集群中的主题和分区,充当分区领导者的代理节点等。

Subscriptions(订阅)——跟踪消费者订阅状态

Deserializers(反序列化器)——记录键和值反序列化器。 反序列化器将字节数组转换为对象。

Partition Assignor — 代表实现 org.apache.kafka.clients.consumer.ConsumerPartitionAssignor 的分区分配策略的完全限定类名

Interceptors(拦截器)——可能改变记录的拦截器

Consumer Coordinator——管理组成员、偏移量

Network Client(网络客户端)——处理对代理的请求

Fetcher——从broker那里获取成批的记录。

配置Kafka Consumer

Kafka Consumer 有四个必需的属性:

bootstrap.servers — 主机/端口对列表,用于建立与 Kafka 集群的初始连接。 格式:“host1:port1,host2:port2,...”

key.deserializer — 代表实现 org.apache.kafka.common.serialization.Deserializer 接口的key反序列化器的完全限定类名。

value.deserializer — 表示实现 org.apache.kafka.common.serialization.Deserializer 接口的value反序列化器的完全限定类名。

group.idopen in new window — 唯一的消费者组 ID。 如果客户端使用 subscribe() 方法来消费消息或使用偏移量管理功能,则需要。

订阅主题

Kafka Consumer 提供了两种订阅主题的方式:通过 subscribe() 和 assign() 方法。 每个都有一组不同的支持功能。

subscribe()

  • 支持订阅主题列表或使用正则表达式
  • 具有消费者故障检测的组成员身份(客户端和服务器端)
  • 动态分区分配
  • 自动或手动偏移量管理
  • 每个分区单个消费者(使用标准分区分配器)

assign()

  • 通过主题分区订阅更好地控制
  • 自动或手动偏移量管理
  • 每个分区支持多个消费者

Apache Flink 和 Spark 使用 assign() 来订阅主题并管理主题-分区对在工作者之间的分布。

消费数据

一旦订阅了主题,用户就可以通过调用 poll() 方法来消费消息。 根据订阅方法的不同,背后会发生几个调用,在下面的序列图中列出。

使用subscribe()消费

在 subscribe() 的情况下,Kafka Consumer 在成为消费者组的活跃成员之前不会消费记录。 我们看到一些团队忽略了这一点,花时间调试停止消费,而根本原因是消费者群体不稳定。

使用assign()消费

在 assign() 的情况下,Kafka Consumer 不会调用组成员资格功能,例如心跳和加入/重新加入消费者组。

Fetcher

无论采用何种订阅方式,Kafka Consumer 都使用 Fetcher 从 broker 中检索批记录。

Fetcher 在内存中保存生产者发送的压缩批次,并在 poll() 上解压缩记录。 一旦批次被消耗,它就会从内存中丢弃。 fetch.min.bytes 和 fetch.max.wait.msopen in new window 是调整 fetcher 吞吐量或延迟的关键配置。 增加字节数和时间将导致吞吐量增加并减少更好的延迟。

消费组

当用户使用 subscribe() 进行消费时,具有相同 group.idopen in new window 的消费者将组成一个消费组,并协作消费 topic(s) 消息。 Kafka 集群将选出其中一个 broker 作为 Group Coordinator。 组协调器负责管理组列表成员、接收心跳、触发组成员更改的重新平衡等。协调器将选举一个消费者作为组长,并要求跨消费者进行分区分配。 每个分区只会分配一个消费者。

消费者组重新平衡

组成员的变化将触发消费者组重新平衡。 在重新平衡期间,组长将重新计算当前成员之间的分区分配。 当发生如下创景时,重新平衡被触发

可能触发消费者组重新平衡的可能原因列表:

  • 服务扩展
  • poll() 和长消息处理发生在同一个线程中
  • 组协调器的心跳失败
  • JVM 垃圾收集暂停
  • Kubernetes PODS CPU 节流
  • Kubernetes 集群升级,导致 POD 逐出
  • 网络问题(延迟、丢包等)

消费者分区分配器

Kafka Consumer 提供了几个选项来选择在重新平衡期间如何分配分区。 用户可以通过 partition.assignment.strategy 配置参数来控制它,其值为实现 org.apache.kafka.clients.consumer.ConsumerPartitionAssignor 的完全限定类名的值。 Kafka 开箱即用地提供以下策略:

范围 - 停止全局策略,以主题为基础。 它可能会产生不平衡的分配。

RoundRobin — 停止全局策略,为相同的订阅统一分配分区。

Sticky——停止全局策略,初始分布会接近RoundRobin。 尝试最小化重新平衡期间移动的分区,可能会产生不平衡的分配。

CooperativeSticky — 在不停止消费的情况下进行增量再平衡。 它与 Sticky 的逻辑相同,但具有增量支持。 这种策略可能会产生不平衡的分配。

评论
  • 按正序
  • 按倒序
  • 按热度
Powered by Waline v2.14.1