From bace3202f5f78dbf0e0c3e66e9c1e5390a6d59fc Mon Sep 17 00:00:00 2001 From: wuxiangkai Date: Sat, 25 Nov 2023 17:14:21 +0800 Subject: [PATCH] =?UTF-8?q?=E9=98=85=E8=AF=BBkafka=20consumer=20commitSync?= =?UTF-8?q?/commitcommitAsync=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- mq/kafka/kafka-尚硅谷.md | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/mq/kafka/kafka-尚硅谷.md b/mq/kafka/kafka-尚硅谷.md index cd27a86..6c434f6 100644 --- a/mq/kafka/kafka-尚硅谷.md +++ b/mq/kafka/kafka-尚硅谷.md @@ -402,13 +402,25 @@ kafka中的分区策略通过`partition.assignment.strategy`参数来进行配 > > - kafka commitSync可手动同步提交offset,但是在调用commitSync接口后,会等待broker返回确认信息,在此之前消费者会一直阻塞。这样会影响消费者的吞吐量,故而,为了提高吞吐量,可以尽量减少commitSync的提交次数 > -> - kafka commitAsync,相比于同步提交,commitAsync在调用后并不会阻塞,而是直接返回,此后可以继续调用poll来继续从broker拉取后续消息。 +> - kafka commitAsync,相比于同步提交,commitAsync在调用后并不会阻塞,而是直接返回,此后可以继续调用poll来继续从broker拉取后续消息。但是,相比同步提交,commitAsync可能在发生rebalance时造成重复消费的情况。 +> +> 在使用异步提交时,如果在发生rebalance之前(rebalance只能发生在poll过程中),commitAsync提交失败,由于commitAsync不会失败重试,故而在分区重新分配后,新分配到该分区的消费者实例将会重新消费之前未提交成功的消息,因此产生了消息的重复消费)。 +> +> 而同步提交时,commitSync在提交失败后会无限次重试,直到提交成功,故而在发生rebalance时(rebalance只能发生在poll的过程中),在发生rebalance之前,可以保证之前commitSync操作已经成功。 > #### kafka的手动提交重试机制 > 针对kafka的手动提交,当使用`commitSync`进行同步提交时,如果提交失败,同步提交会无限次的进行重试,直到提交成功或是发生了不可恢复的异常。 > > 但是,在使用`commitAsync`方法进行提交时,kafka消费者在提交失败之后则不会进行重试。在处理kafka commitAsync重试问题时,还需要考虑commit order。当消费者进行异步提交时,如果发现当前batch提交失败,此时可能位于当前batch之后的batch已经处理完成并进行提交(commitAsync并不会等待当前batch提交成功之后再拉取下一批,而是直接拉取下一批继续处理,故而下一批batch可能提交早于当前batch)。故而,如果对当前异常的batch进行重试提交,可能会之后批次的commit offset被覆盖,从而造成消息的重复消费。 +##### rebalance +rebalance通常有两个阶段,`revocation`和`assignment`,即撤销当前消费者被分配的分区和重新分配给消费者新的分区。revocation方法会在rebalance之前被调用,且revocation是rebalance之前消费者最后一次提交offset的机会,可以重写revocation方法,在rebalance发生之前对offset进行同步提交。 + +而assignment则是发生在rebalance之后,可以重写assignment方法来初始化各分区的offset。 + +通常情况下,commitAsync相较commitSync是更不安全的,在宕机之前提交失败将会造成消息的重复消费。可以通过在回调中使用commitSync来减轻消息的重复消费风险。 + +