kafka 數據丟失和數據重復的原因和解決辦法


數據丟失的原因
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 中拉取消息進行同步
————————————————
版權聲明:本文為CSDN博主「RayfunC」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/a308601801/article/details/88642985


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM