4、Kafka消费者-从Kafka读取数据

1、消费者和消费者群组

(1)消息模型:队列模型(queuing)    发布-订阅模型(publish-subscribe)

(2)Kafka两种模型提供单一消费者模型: 消费者组。 消费者用组名标记自己Topic上消息发给此组中一个消费者。 1)所有消费者在一个组中,变成队列。 2)不同的组中,变成发布-订阅。 

消费者(一个组)订同一Topic,每个接受一部分分区消息,实现扩展分流。场景:单个消费者无法跟上数据生成的速度

多个应用程序从同Topic读取所有的消息,保证有自己的消费者组即可,都能获取Topic全部消息;

2、Partition Rebalance分区再均衡

三种现象使partition所有权消费者间转移,这样行为叫再均衡

(1)消费者组中添加消费者读取到原本是,其他消费者读取的消息

(2)消费者关闭或崩溃后离开群组,他读取的partition组里其他消费者读(3)向Topic添加新的partition,partition在消费者中重新分配

优点:消费者组高可用性伸缩性

缺点:1)期间消费者无法读取消息,有小段不可用     2)partition被重新分配给一个消费者时,消费者当前的读取状态会丢失,有可能还需要去刷新缓存,在它重新恢复状态之前会拖慢应用程序。

另:新版心跳变化(消费者向broker发心跳):1)独立心跳线程,轮询msg空档发心跳。2)指定不发心跳时间,避免活锁。

3、创建Kafka消费者、订阅主题、轮询

4、消费者的配置

1:fetch.min.bytes,消费者从broker获取消息的最小字节数,足够才返回

2:fetch.max.wait.ms,等待broker返回最大时间,默认500ms。和上面哪个先满足,就按哪种

3:max.partition.fetch.bytes,broker从每个partition中返回最大字节数,默认1MB

4:session.timeout.ms,死亡之前与服务器断开连接时间,默认3s

5:auto.offset.reset,读没有偏移量或者无效(消费者长时间失效,偏移量过时被删除)该作何处理。默认latest(消费者从最新读)。另一个earliest

6:enable.auto.commit,是否自动提交偏移量,默认true

7:partition.assignment.strategy,partition如何分配给消费者,默认Range:把Topic的若干个连续partition分配给消费者。RoundRobin:Topic所有partition逐个分配给消费者

8:max.poll.records,poll方法返回消息数

5、提交和偏移量

再均衡后,读partition最后偏移量,从指定地方处理。

(1)提交可能带来问题:小于客户端处理最后偏移量,两个偏移量之间消息重复处理;大于丢失

(2)提交方式:

1)自动提交:默认为true 5s  

2)false:broker在对提交请求,回应前一直阻塞,限制吞吐量

3)异步提交:commitAsync后不重试,问题:提交偏移量2000,短暂通信问题,处理另外一批提交3000,。重新提交2000,这时候如再均衡,出现重复消息

4)同、异步组合提交:消费者关闭前用

6、再均衡监听器

平衡前,消费者知道即将不负责某分区,提交已处理过消息位移。调用subscribe()传ConsumerRebalanceListener对象有两个方法:

onPartitionRevoked(Collection partitions):停止消费后,重平衡前调用。

onPartitionAssigned(Collection partitions):读取消息前用。

7、从指定位移开始消费

分区开始/末端:seekToBeginning(TopicPartition tp)    seekToEnd(TopicPartition tp)。

支持从指定位移开始消费:场景:位移存在其他系统(如数据库)中,并以db位移为准:保存db成功,提交位移到Kafka失败,消息会重复处理。不能优化方案为原子性操作,因此保存到数据库同时,保存位移seek()来指定分区位移

8、优雅退出

退出poll循环时,用另一个线程调用consumer.wakeup(),poll()抛出WakeupException。

如wakup时,正在处理消息,那么poll时会抛出异常。解决:抛出WakeUpException后,调用consumer.close(),提交位移,同时发送退出消息到Kafka组协调者,重平衡

9、用Avro反序列化

你可能感兴趣的:(4、Kafka消费者-从Kafka读取数据)