【kafka】---kafka的pull模型

一、pull和push模型

消费系统主要有两种模型推送或消费消息。

push:优势在于消息实时性高,劣势在于没考虑comsumer消费能力和饱和情况,容易导致producer压垮consumer。
消息中转代理将消息推送到消费者后,标记这条消息已经消费,但这种方式无法保证消息被消费处理。如果要保证消息被处理,消息代理发送完消息后标记“已发送”,再消费者确认消费了回复后变成“已消费”。这需要消费中转代理记录所有消息状态,显然很不切合实际。

pull:优势在于可以控制消费速度和消费数量,保证comsumer不会出现饱和。劣势在于没数据时,会出现空轮询,消耗CPU【kafka可以通过配置参数来保证当存在数据且达到一定数量才开始pull操作】。

二、kafka consumer的pull模型

由消费者自己记录消费状态,每个消费者互相独立地顺序拉取每个分区的消息。
Kafka采用整数值position记录单个分区的消费状态,且单个分区的单个消息只能被一个consumer group的一个consumer消费。消费完了,broker收到确认,position指向下一个offset。 由于消息一定时间内不清除,那么可以重置offset来重新消费消息。

1、offset管理

每个consumer group、每个topic的每个partition都有各自的offset。
按照kafka-0.10.1.X版本之前和之后版本,offset的管理方式也不同。
kafka-0.10.1.X版本之前:通过Zookeeper来管理;
Zookeeper:老版本的offset是提交到zookeeper,目录结构是 :/consumers/<group.id>/offsets/ / 。 如果频繁的offset更新时,ZK集群本身 是瓶颈【不推荐使用】。

kafka-0.10.1.X版本之后:kafka集群的一个topic(_consumer_offsets)来管理。
Kafka的自身一个topic(_consumer_offsets):能支持大吞吐量的offset更新。

2、Kafka的自身一个topic管理offset

新的kafka版本是kafka集群broker来管理,这样主要是自动提交手动提交

(1)、自动提交

配置如下

"enable.auto.commit":true
#auto.commit.interval.ms设置为一个较低的时间范围,偏移量自动提交到Kafka的频率(以毫秒为单位)
auto.commit.interval.ms=6000

有专门线程定时间隔将offset提交到kafka集群的topic上。

自动提交会引起At-most-onceAt-least-once问题。
At-most-once
消费者的offset已经提交,但消息还在处理,这时候挂了,再重启时从上一次offset处消费,导致上次在处理的消息部分丢失。

At-least-once
消费者已经处理完,但offset还未提交,这时候消费者挂了,会导致重复消息处理。auto.commit.interval.ms设置为一个较低的时间范围,那么这种情况出现概率小。

(2)、手动提交

配置如下

"enable.auto.commit":false
消息处理完后手动调用consumer.commitSync()。

手动提交会引起At-least-once问题。
At-least-once
一次poll后,手动调用offset异步提交函数。
如果消费者消息处理完后,offset还未提交,此时消费者挂了,重启后会重新消费把那个处理消息。

3、pull模式优缺点

pull模式可以根据consumer的消费能力以适当的速率消费消息。
不足之处:如果Kafka没有数据,消费者一直返回空数据。
解决方法:kafka消费者从消费数据时传入timeout参数,在这个时间范围内进行阻塞等待,直到有数据或超时后再返回。

猜你喜欢

转载自blog.csdn.net/xunmengyou1990/article/details/108551648
今日推荐