kafka 中 auto commit 的操作

1,581 阅读2分钟

网上很多博客对 auto commit 的介绍都是错误的,例如下面这位通过 auto commit 来推导出消费者少消费数据的场景

当消费者拉取到了分区的某个消息之后,消费者会自动提交了 offset。自动提交的话会有一个问题,试想一下,当消费者刚拿到这个消息准备进行真正消费的时候,突然挂掉了,消息实际上并没有被消费,但是 offset 却被自动提交了。

其实我一开始也是对其有误解的,因为参数enable_auto_commitauto_commit_interval_ms的配合实在是太好了,一个表示自动提交,一个表示自动提交的时间间隔,然后不就是正常的推导出每隔auto_commit_interval_msauto commit一下吗!

如果是这样的话,那么提交的过程就和poll数据的过程相互独立了,这样做是有问题的!比如我 10s 才消费完一次poll的数据,此时设置的auto_commit_interval_ms是 3s,那么消费者commit就提交了三回了,提交了个啥?我只拉了一回数据啊。所以是解释不通的。

所以上网搜了下自动提交到底是如何提交的,stack_overflow上面有一个标准的解答

The auto-commit check is called in every poll and it checks that the time elapsed is greater than the configured time. If so, the offset is committed.

In case the commit interval is 5 seconds and poll is happening in 7 seconds, the commit will happen after 7 seconds only.

这个就解释的通了,每次poll数据的时候,会检查当前时间是否超过了设置的自动提交时间间隔,如果超过了就进行提交,否则不提交。

如果有消费者在超过了auto_commit_interval_ms的时候,挂掉了。那么在没有poll之前,是不会提交的,然后重启后消费的还是这波数据。所以开头截取的内容是错误的。

这个其实很容就可以尝试的,本地整一个单机的kafka,消费数据的时候,sleep 个 5.1s(因为默认的auto_commit_interval_ms是5s),然后主动抛异常。在下次进行消费的时候,查看消费的数据是否还是上次的消息就好了。