Kafka学习笔记-- 3 Kafka use case

目录

 

1 exactly once的实现

1 producer只生产了一次消息

2 consumer 只消费了一次消息

2 如何数据处理时间不可控, 因为长时间不poll导致consumer退出的问题? 


1 exactly once的实现

exactly once是指消息不多不少, 只消费了一次。 与exactly once相对应的, 还有: at least once 消息最少消费一次, 允许消费多次;at most once, 消息最多消费一次, 允许少消费。 

这里的exactly once的实现, 是在整个kafka系统没有都崩溃了的前提下的。

可以对这个问题进行分解, 分解为两个子问题: 

  1. producer不多不少, 只生产了一次消息;
  2. consumer不多不少, 只消费了一次消息;

前提: broker的数量为3个以上, replication的数量为3个以上;整个kafka系统没有都崩溃; producer不崩溃的情况下。 

三种异常情况: 一个partition至少有一个replication存活, producer, consumer崩溃.

1 producer只生产了一次消息

不会少生产消息: producer设置acks参数为all, 这样broker返回成功时, 这个消息就已经保存在了kafka中了。 不管时producer崩溃还是一些broker崩溃, 都没有办法影响到这个消息落地。 

不会多生产消息: 这个由生产者的自己的业务代码决定;

2 consumer 只消费了一次消息

不会少消费消息:消费成功后, 需要commit 当前已经消费的offset。 这种情况, 当consumer崩溃时, 会从最新的comiit offset开始消费消息, 这可能会出现一部分的重复, 拿到那些已经消费但是未来得及提交的数据; 如果broker没有全都崩溃, 也无法影响消息的消费。 到这里, 我们就已经实现了at least once。

不会多消费消息:要保证无法多消费消息, 则需要在不会少消费消息的基础上, 保证从消费成功, 到提交kafka这个操作是一个事务性操作, 要么都成功, 要么都失败。 一般来说消费成功的标识是入库成功, 可以通过把offset存放到数据库等存储系统的方法来实现,下次启动时从数据库中的offset开始消费。  具体可以有两种方式:

支持事务的存储系统, 如关系数据库, 把提交offset和提交入库数据作为一个事务提交;

如果不支持事务, 但是对于一个数据记录的存储也可以保证原子性, 可以把offset信息放在数据记录中;(当然这种方法对于关系数据库也是ok的)

综上, 就已经实现了exactly once的语义。 

2 如何数据处理时间不可控, 因为长时间不poll导致consumer退出的问题? 

使用后台线程进行数据处理。 需要调整的kafka相关的东西:

  • 关闭自动提交;(默认是开启自动提交的, 当poll时, 就会自动提交上一条数据)
  • 消息消费完成之后才commit;
  • 获取一批消息之后 pause 分区, 确保没有消费完消息之前不会收到新的消息;
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章