kafka版本:0.10.2
問(wèn)題描述
上篇文章中需频,我們?cè)趐roducer代碼里增加了reties參數(shù)猪落,看似解決了partition leader選舉帶來(lái)的程序異常問(wèn)題蚌铜, 但實(shí)際隱藏了一個(gè)更為嚴(yán)重的問(wèn)題:leader 選舉過(guò)程中处面,producer 重試發(fā)送過(guò)程中钳降,數(shù)據(jù)存在丟失的現(xiàn)象漾根。
設(shè)置如下三個(gè)參數(shù)值泰涂,方可保證發(fā)送數(shù)據(jù)不丟失
- unclean.leader.election.enable=false (在server.properties文件中配置)
- min.insync.replicas=總副本數(shù)-1 ,即最小同步副本個(gè)數(shù)=總副本個(gè)數(shù)-1(在server.properties文件中配置)
- acks=-1/all立叛,即當(dāng)所有isr副本數(shù)全部收到消費(fèi)之后再提交ack (在producer端代碼里配置)
考慮在使用上述參數(shù)默認(rèn)值的情況下负敏,消息為什么會(huì)丟失?
unclean.leader.election.enable=true :表示當(dāng)該分區(qū)所有副本代理都下線的情況下秘蛇,Kafka 會(huì)選第一個(gè)上線的代理作為 leader其做,而不管它下線之前是不是在 ISR中顶考,那么如果這個(gè)新 leader 下線之前并不是 leader 或者不在 ISR 中,有一部分消息便丟失了妖泄。我們?cè)O(shè)置成 false,可以保證非 ISR 節(jié)點(diǎn)不可以參與選舉驹沿。
ack=1,即當(dāng)leader收到消息后蹈胡,就認(rèn)為消息發(fā)送成功了渊季,不關(guān)心其他isr副本是否接收到。注意是isr(在線副本) 而不是asr(所有副本)
min.insync.replicas=1 : 最小同步副本數(shù)默認(rèn)為1罚渐,producer在生產(chǎn)的時(shí)候需要確認(rèn)broker節(jié)點(diǎn)是否滿足最小同步副本數(shù)却汉,即 isr節(jié)點(diǎn)的個(gè)數(shù)是否>=1。滿足荷并,才認(rèn)為發(fā)送成功合砂,不滿足,produer端會(huì)拋出錯(cuò)誤源织,Error: NOT_ENOUGH_REPLICAS 翩伪。當(dāng) min.insync.replicas=副本數(shù)-1,這樣便達(dá)到了消息發(fā)送成功的最強(qiáng)保障谈息。
結(jié)論:unclean.leader.election.enable=false,Kafka 會(huì)在該分區(qū)所有副本代理都下線的情況下缘屹,從 ISR 中選擇第一個(gè)上線的代理作為 leader。ack=-1 和 min.insync.replicas= 總副本數(shù)-1共同作用:要求生產(chǎn)時(shí)侠仇,需要得到該分區(qū)所有在線副本代理的確認(rèn)轻姿,并且確認(rèn)在線副本數(shù)要大于等于(副本數(shù)-1),這樣就保證了每次生產(chǎn)傅瞻,有絕大多數(shù)副本代理確認(rèn)收到消息后才認(rèn)為消息已成功寫(xiě)入 Kafka踢代。這樣如果在非常情況下進(jìn)行 leader 選舉,Kafka 既能很快恢復(fù)嗅骄,也保障了數(shù)據(jù)不丟失。
學(xué)無(wú)止境
- isr : 已同步的副本集饼疙,是說(shuō)在一段時(shí)間內(nèi)和leader同步的副本們溺森,那當(dāng)數(shù)據(jù)量吞吐量一旦上來(lái),producer生產(chǎn)遇到leader選舉窑眯,還會(huì)不會(huì)丟數(shù)屏积?
- 遇到kafka集群不健康,producer發(fā)送遇到leader選舉磅甩,重試過(guò)程中炊林,還是遇到了最小同步副本數(shù)不滿足的情況,依然需要我們重啟程序來(lái)處理異常卷要。后續(xù)我們適當(dāng)擴(kuò)大了topic的副本數(shù)渣聚,目前已經(jīng)處于穩(wěn)定狀態(tài)了