Spark消費Kafka如何實現精准一次性消費?


1.定義

  • 精確一次消費(Exactly-once) 是指消息一定會被處理且只會被處理一次。不多不少就一次處理。

如果達不到精確一次消費,可能會達到另外兩種情況:

  • 至少一次消費(at least once),主要是保證數據不會丟失,但有可能存在數據重復問題。

  • 最多一次消費 (at most once),主要是保證數據不會重復,但有可能存在數據丟失問題。

如果同時解決了數據丟失和數據重復的問題,那么就實現了精確一次消費的語義了。

2. 問題如何產生

數據何時會丟失: 比如實時計算任務進行計算,到數據結果存盤之前,進程崩潰,假設在進程崩潰前kafka調整了偏移量,那么kafka就會認為數據已經被處理過,即使進程重啟,kafka也會從新的偏移量開始,所以之前沒有保存的數據就被丟失掉了。

數據何時會重復: 如果數據計算結果已經存盤了,在kafka調整偏移量之前,進程崩潰,那么kafka會認為數據沒有被消費,進程重啟,會重新從舊的偏移量開始,那么數據就會被2次消費,又會被存盤,數據就被存了2遍,造成數據重復。

3.解決方案

方案一:利用關系型數據庫的事務進行處理

出現丟失或者重復的問題,核心就是偏移量的提交與數據的保存,不是原子性的。如果能做成要么數據保存和偏移量都成功,要么兩個失敗。那么就不會出現丟失或者重復了。

這樣的話可以把存數據和偏移量放到一個事務里。這樣就做到前面的成功,如果后面做失敗了,就回滾前面那么就達成了原子性。

問題與限制

  1. 數據庫選型受限, 只能使用支持事務的關系型數據庫 ,如mysql, oracle ,無法使用其他功能強大的nosql數據庫。

  2. 如果保存的數據量較大一個數據庫節點不夠,多個節點的話,還要考慮分布式事務的問題。做分布式事務,結構復雜,拖慢性能。

  3. 如果做本地事務 ,只能把分區數據提取到driver中進行保存,降低並發 ,增加executor到driver的數據傳遞io。

方案二:手動提交偏移量+冪等性處理

咱們知道如果能夠同時解決數據丟失和數據重復問題,就等於做到了精確一次消費。

那咱們就各個擊破。

首先解決數據丟失問題,辦法就是要等數據保存成功后再提交偏移量,所以就必須手工來控制偏移量的提交時機。

但是如果數據保存了,沒等偏移量提交進程掛了,數據會被重復消費。怎么辦?那就要把數據的保存做成冪等性保存。即同一批數據反復保存多次,數據不會翻倍,保存一次和保存一百次的效果是一樣的。如果能做到這個,就達到了冪等性保存,就不用擔心數據會重復了。

難點

話雖如此,在實際的開發中手動提交偏移量其實不難,難的是冪等性的保存,有的時候並不一定能保證。所以有的時候只能優先保證的數據不丟失。數據重復難以避免。即只保證了至少一次消費的語義。

 

文章來源:https://blog.csdn.net/wangsl754/article/details/107479977?


免責聲明!

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



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