Kafka--消费者

应用程序使用KafkaConsumer向Kafka订阅主题,并从订阅的主题上接受消息。

消费者和消费者群组

消费者对象用于订阅主题并接收消息,然后验证消息并保存结果。

Kafka消费者从属于消费者群组。一个群组里的消费者订阅的是同一个主题,每个消费者接收主题一部分分区的消息。

如果一个消费者群组里的消费者数量大于主题分区数量,那么有一部分消费者就会被闲置,不会接收到任何消息。

一个新的消费者加入群组时,它读取的是原本由其他消费者读取的消息。当一个消费者被关闭或发生崩溃时,它就离开群组,原本由它选取的分区将由群组里的其他消费者来读取。

往群组里增加消费者是横向伸缩消费能力的主要方式。

我们有必要为主题创建大量的分区,在负载增长时可以加入更多的消费者。

不同于传统的消息系统,横向伸缩Kafka消费者和消费者群组并不会对性能造成负面影响。

分区再均衡

分区的所有权从一个消费者转移到另一个消费者,这样的行为被称为再均衡。

再均衡为消费者群组带来了高可用性和伸缩性。

正常情况下,我们并不希望发生这样的行为。

在再均衡期间,消费者无法读取消息,造成整个群组一小段时间的不可用。另外,当分区被重新分配给另一个消费者时,消费者当前的读取状态会丢失,它有可能还需要去刷新缓存,在它重新恢复状态之前会拖慢应用程序。

消费者通过向被指派群组协调器的broker(不同群组可以有不同的协调器)发送心跳来维持他们的群组的从属关系以及他们对分区的所有权关系。

只要消费者以正常的时间间隔发送心跳,就被认为是活跃的,说明它还在读取分区里的消息。

消费者会在轮询消息(为了获取消息)或提交偏移量时发送心跳。

如果消费者停止发送心跳的时间足够长,会话就会过期,群组协调器认为它已经死亡,就会触发一次再均衡。

如果一个消费者发生崩溃,并停止读取消息,群组协调器会等待几秒钟,确认它死亡了才会触发再均衡。

在清理消费者时,消费者会通知协调器它将要离开群组,协调器会立即触发一次再均衡,尽量降低处理停顿。

如果需要处理耗费较长时间的消息,可以加大max.poll.interval.ms的值来增加轮询间隔的市场。

分区分配

当消费者要加入群组时,它会像群组协调器发送一个JoinGroup请求。第一个加入群组的消费者将成为群主。

群主从协调器那里获得群组的成员列表,并负责给每一个消费者分配分区。它使用一个实现了PartitionAssignor接口的类来决定哪些分区应该被分配给哪个消费者。

Kafka内置了两种分配策略。分配完毕之后,群主把分配情况列表发送给群组协调器,协调器再把这些消息发送给所有消费者。

每个消费者只能看到自己的分配信息,只有群主知道群组里所有消费者的分配信息。

这个过程会在每次再均衡时重复发生。

轮询

消息轮询时消费者API的核心,通过一个简单的轮询向服务器请求数据。

一旦消费者订阅了主题,轮询就会处理所有的细节,包括群组协调,分区再均衡,发送心跳和获取数据。

消费者必须持续对Kafka进行轮询(poll),否则会被认为已经死亡。

poll()方法会返回一个记录列表。每条记录都包含了记录所属主题的信息,记录所在分区的信息,记录在分区里的偏移量,以及记录的键值对。

在推出应用程序之前使用close()方法关闭消费者。网络连接和socker也会随之关闭,并立即触发一次再均衡,而不是等待群组协调器发现它不再发送心跳并认定它已死亡,因为那样需要更长时间,导致整个群组在一段时间内无法读取消息。

轮询不只是获取数据那么简单,在第一次调用新消费者的poll()方法时,它会负责查找GroupCoordinator,然后加入群组,接受分配的分区。

如果发生了再均衡,整个过程也是在轮询期间进行的。当然,心跳也是从轮询里发送出去的。

在同一个群组里,我们无法让一个线程运行多个消费者,也无法让多个线程安全地共享一个消费者。

按照规则,一个消费者使用使用一个县城。

如果要在同一个消费者群组里运行多个消费者,需要让每个消费者运行在自己的线程里。

最好是把消费者的逻辑封装在自己的对象里,然后使用Java的线程池启动多个线程,使每个消费者运行在自己的线程上。

消费者配置

bootstrap.servers

group.id

key.deserializer

value.deserializer

fetch.min.bytes

fetch.max.wait.ms

max.partition.fetch.bytes

session.timeout.ms

auto.offset.reset

enable.auto.commit

partition.assignmeng.strategy

client.id

max.poll.records

receive.buffer.bytes

send.buffer.bytes

提交和偏移量

猜你喜欢

转载自www.cnblogs.com/microcat/p/11444248.html