Kafka Reblance & max.poll.interval.ms 重復(fù)消費(fèi)問(wèn)題
1. 什么是kafka Reblance?
消費(fèi)組是MQ中一個(gè)非常重要的概念,一個(gè)消費(fèi)組監(jiān)聽(tīng)一個(gè)Topic時(shí),Kafka服務(wù)端會(huì)給消費(fèi)組中的每一個(gè)實(shí)例,進(jìn)行隊(duì)列分配,每一個(gè)實(shí)例指定消費(fèi)一個(gè)或多個(gè)隊(duì)列(分區(qū)),當(dāng)然如果消費(fèi)實(shí)例數(shù)量如果超出了隊(duì)列數(shù)量,那么會(huì)出現(xiàn)消費(fèi)實(shí)例不監(jiān)聽(tīng)任何隊(duì)列的情況。
當(dāng)一個(gè)消費(fèi)實(shí)例加入或者退出消費(fèi)組時(shí),那么消費(fèi)實(shí)例的數(shù)量會(huì)變化,服務(wù)端有責(zé)任將消息隊(duì)列(分區(qū)), 盡可能均衡的平分給所有消費(fèi)實(shí)例,這時(shí)就會(huì)出現(xiàn)rebalance。
2. 什么是max.poll.interval.ms?
max.poll.interval.ms 消費(fèi)端的配置參數(shù):最大poll間隔毫秒數(shù),指定兩次poll的最大間隔,默認(rèn)5分鐘。如果超出了,那么Kafka服務(wù)端會(huì)認(rèn)為當(dāng)前消費(fèi)實(shí)例,已經(jīng)不可用了,那么這個(gè)時(shí)候消費(fèi)組的實(shí)例數(shù)量就會(huì)減1,同步導(dǎo)致需要rebalance。
3. 重復(fù)消費(fèi)在什么情況下會(huì)和以上信息產(chǎn)生關(guān)聯(lián)?
當(dāng)一個(gè)消費(fèi)實(shí)例poll一次之后,進(jìn)行業(yè)務(wù)邏輯處理,如果處理的時(shí)間過(guò)長(zhǎng),超出了max.poll.interval.ms,此時(shí)雖然消費(fèi)實(shí)例依然活著,但是Kafka服務(wù)端已經(jīng)認(rèn)為該實(shí)例不可用,那么進(jìn)行reblance,把當(dāng)前屬于該實(shí)例的隊(duì)列(分區(qū)) 分配給其他實(shí)例,由于這些被消費(fèi)的隊(duì)列的offset還沒(méi)有被提交,導(dǎo)致新的消費(fèi)實(shí)例會(huì)重新消費(fèi)當(dāng)前的消息。
4. 合理的建議
一次poll少量的數(shù)據(jù)保證業(yè)務(wù)處理時(shí)間不會(huì)超出 max.poll.interval.ms 的配置,同時(shí)增加消費(fèi)的冪等邏輯。
5. 為什么Kafka會(huì)用poll的頻率來(lái)判定實(shí)例的死活呢?
通常判定實(shí)例的可用性,一般是通過(guò)心跳機(jī)制來(lái)實(shí)現(xiàn),但是似乎早期的Kafka沒(méi)有心跳機(jī)制,且消費(fèi)端的poll輪詢,在某種程度上等同于心跳,所以才會(huì)有通過(guò)poll頻率來(lái)判定實(shí)例是否可用。KIP-62及之后,引入了單獨(dú)的心跳線程,max.poll.interval.ms是poll最大間隔秒數(shù),session.timeout.ms是心跳間隔最大秒數(shù),默認(rèn)30秒,不論哪一個(gè)超時(shí)都會(huì)導(dǎo)致消費(fèi)實(shí)例被下線。具體可參見(jiàn)這個(gè)stackOverFlow里的這個(gè)回答
posted on 2022-12-30 15:42 mindSucker 閱讀(871) 評(píng)論(0) 收藏 舉報(bào)
浙公網(wǎng)安備 33010602011771號(hào)