【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-once和At-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还未提交,此时消费者挂了,重启后会重新消费把那个处理消息。
上一篇: Kafka问题
下一篇: PHPExcel导出纵向合并单元格