Kafka 資料丟失和資料重複的原因和解決辦法

2021-09-12 20:25:03 字數 1604 閱讀 8914

kafka 訊息傳送分同步 (sync)、非同步 (async) 兩種方式,預設使用同步方式,可通過 producer.type 屬性進行配置;

通過 request.required.acks 屬性進行配置:值可設為 0, 1, -1(all)    -1 和 all 等同

0 代表:不等待 broker 的 ack,這一操作提供了乙個最低的延遲,broker 一接收到還沒有寫入磁碟就已經返回,當 broker 故障時有可能丟失資料;

1 代表:producer 等待 broker 的 ack,partition 的 leader 落盤成功後返回 ack,如果在 follower 同步成功之前 leader 故障,那麼將會丟失資料;

-1 代表:producer 等待 broker 的 ack,partition 的 leader 和 follower 全部落盤成功後才返回 ack,資料一般不會丟失,延遲時間長但是可靠性高;但是這樣也不能保證資料不丟失,比如當 isr 中只有 leader 時( isr 中的成員由於某些情況會增加也會減少,最少就只剩乙個 leader),這樣就變成了 acks = 1 的情況;

另外乙個就是使用高階消費者存在資料丟失的隱患: 消費者讀取完成,高階消費者 api 的 offset 已經提交,但是還沒有處理完成spark streaming 掛掉,此時 offset 已經更新,無法再消費之前丟失的資料. 解決辦法使用低階消費者

acks = -1 的情況下,資料傳送到 leader 後 ,部分 isr 的副本同步,leader 此時掛掉。比如 follower1 和 follower2 都有可能變成新的 leader, producer 端會得到返回異常,producer 端會重新傳送資料,資料可能會重複

另外, 在高階消費者中,offset 採用自動提交的方式, 自動提交時,假設 1s 提交一次 offset 的更新,設當前 offset = 10,當消費者消費了 0.5s 的資料,offset 移動了 15,由於提交間隔為 1s,因此這一 offset 的更新並不會被提交,這時候我們寫的消費者掛掉,重啟後,消費者會去 zookeeper 上獲取讀取位置,獲取到的 offset 仍為10,它就會重複消費. 解決辦法使用低階消費者

設定同步模式, producer.type = sync, request.required.acks =  -1, replication.factor >= 2 且 min.insync.replicas >= 2

這裡需要 hw ( highwartermark ) 的協同配合。類似於木桶原理,水位取決於最低那塊短板

某個 topic 的某 partition 有三個副本,分別為 a、b、c。a 作為 leader 肯定是 leo 最高,b 緊隨其後,c 機器由於配置比較低,網路比較差,故而同步最慢。這個時候 a 機器宕機,這時候如果 b 成為 leader,假如沒有 hw,在 a 重新恢復之後會做同步(makefollower) 操作,在宕機時 log 檔案之後直接做追加操作,而假如 b 的 leo 已經達到了 a 的 leo,會產生資料不一致的情況

解決辦法就是: a 在做同步操作的時候,先將 log 檔案截斷到之前自己的 hw 的位置,即 3,之後再從 b 中拉取訊息進行同步

kafka丟失和重複消費資料

kafka作為當下流行的高併發訊息中介軟體,大量用於資料採集,實時處理等場景,我們在享受他的高併發,高可靠時,還是不得不面對可能存在的問題,最常見的就是丟包,重發問題。1 丟包問題 訊息推送服務,每天早上,手機上各終端都會給使用者推送訊息,這時候流量劇增,可能會出現kafka傳送資料過快,導致伺服器...

Kafka 訊息丟失和訊息重複消費

producer 的acks引數值設定為 0 或者 1 不等待伺服器確認或者只讓leader確認解決方法 將acks的值設定為all或者 1,讓leader和followers全部進行確認 producer 沒有設定失敗重試解決方法 根據實際場景將retries引數值設定為正整數 consumerp...

Kafka 訊息丟失和訊息重複消費

producer 的acks引數值設定為 0 或者 1 不等待伺服器確認或者只讓leader確認解決方法 將acks的值設定為all或者 1,讓leader和followers全部進行確認 producer 沒有設定失敗重試解決方法 根據實際場景將retries引數值設定為正整數 consumerp...