寫入內容丟失,各種資料庫或者儲存系統如何處理?

2021-09-25 19:23:14 字數 3468 閱讀 3711

突發宕機,kafka寫入的資料如何保證不丟失?

我們暫且不考慮寫磁碟的具體過程,先大致看看下面的圖,這代表了 kafka 的核心架構原理。

kafka 分布式儲存架構

那麼現在問題來了,如果每天產生幾十 tb 的資料,難道都寫一台機器的磁碟上嗎?這明顯是不靠譜的啊!

所以說,這裡就得考慮資料的分布式儲存了,我們結合 kafka 的具體情況來說說。

在 kafka 裡面,有乙個核心的概念叫做「topic」,這個 topic 你就姑且認為是乙個資料集合吧。

舉個例子,如果你現在有乙份**的使用者行為資料要寫入 kafka,你可以搞乙個 topic 叫做「user_access_log_topic」,這裡寫入的都是使用者行為資料。

然後如果你要把電商**的訂單資料的增刪改變更記錄寫 kafka,那可以搞乙個 topic 叫做「order_tb_topic」,這裡寫入的都是訂單表的變更記錄。

然後假如說咱們舉個例子,就說這個使用者行為 topic 吧,裡面如果每天寫入幾十 tb 的資料,你覺得都放一台機器上靠譜嗎?

明顯不太靠譜,所以 kafka 有乙個概念叫做 partition,就是把乙個 topic 資料集合拆分為多個資料分割槽,你可以認為是多個資料分片,每個 partition 可以在不同的機器上,儲存部分資料。

這樣,不就可以把乙個超大的資料集合分布式儲存在多台機器上了嗎?大家看下圖,一起來體會一下。

kafka 高可用架構

但是這個時候,我們又會遇到乙個問題,就是萬一某台機器宕機了,這台機器上的那個 partition 管理的資料不就丟失了嗎?

所以說,我們還得做多副本冗餘,每個 partition 都可以搞乙個副本放在別的機器上,這樣某台機器宕機,只不過是 partition 其中乙個副本丟失。

如果某個 partition 有多副本的話,kafka 會選舉其中乙個 parititon 副本作為 leader,然後其他的 partition 副本是 follower。

只有 leader partition 是對外提供讀寫操作的,follower partition 就是從 leader partition 同步資料。

一旦 leader partition 宕機了,就會選舉其他的 follower partition 作為新的 leader partition 對外提供讀寫服務,這不就實現了高可用架構了?

kafka 寫入資料丟失問題

現在我們來看看,什麼情況下 kafka 中寫入資料會丟失呢?其實也很簡單,大家都知道寫入資料都是往某個 partition 的 leader 寫入的,然後那個 partition 的 follower 會從 leader 同步資料。

但是萬一 1 條資料剛寫入 leader partition,還沒來得及同步給 follower,此時 leader partiton 所在機器突然就宕機了呢?

大家看下圖:

如上圖,這個時候有一條資料是沒同步到 partition0 的 follower 上去的,然後 partition0 的 leader 所在機器宕機了。

此時就會選舉 partition0 的 follower 作為新的 leader 對外提供服務,然後使用者是不是就讀不到剛才寫入的那條資料了?

因為 partition0 的 follower 上是沒有同步到最新的一條資料的。這個時候就會造成資料丟失的問題。

kafka 的 isr 機制是什麼?

現在我們先留著這個問題不說具體怎麼解決,先回過頭來看乙個 kafka 的核心機制,就是 isr 機制。

這個機制簡單來說,就是會自動給每個 partition 維護乙個 isr 列表,這個列表裡一定會有 leader,然後還會包含跟 leader 保持同步的 follower。

也就是說,只要 leader 的某個 follower 一直跟他保持資料同步,那麼就會存在於 isr 列表裡。

但是如果 follower 因為自身發生一些問題,導致不能及時的從 leader 同步資料過去,那麼這個 follower 就會被認為是「out-of-sync」,被從 isr 列表裡踢出去。

所以大家先得明白這個 isr 是什麼,說白了,就是 kafka 自動維護和監控哪些 follower 及時的跟上了 leader 的資料同步。

kafka 寫入的資料如何保證不丟失?

所以如果要讓寫入 kafka 的資料不丟失,你需要保證如下幾點:

好!現在咱們來分析一下上面幾點要求。

第一條,必須要求至少乙個 follower 在 isr 列表裡。

那必須的啊,要是 leader 沒有 follower 了,或者是 follower 都沒法及時同步 leader 資料,那麼這個事兒肯定就沒法弄下去了。

第二條,每次寫入資料的時候,要求 leader 寫入成功以外,至少乙個 isr 裡的 follower 也寫成功。

大家看下面的圖,這個要求就是保證說,每次寫資料,必須是 leader 和 follower 都寫成功了,才能算是寫成功,保證一條資料必須有兩個以上的副本。

這個時候萬一 leader 宕機,就可以切換到那個 follower 上去,那麼 follower 上是有剛寫入的資料的,此時資料就不會丟失了。

如上圖所示,假如現在 leader 沒有 follower 了,或者是剛寫入 leader,leader 立馬就宕機,還沒來得及同步給 follower。

在這種情況下,寫入就會失敗,然後你就讓生產者不停的重試,直到 kafka 恢復正常滿足上述條件,才能繼續寫入。這樣就可以讓寫入 kafka 的資料不丟失。

總結最後總結一下,其實 kafka 的資料丟失問題,涉及到方方面面。

譬如生產端的快取問題,包括消費端的問題,同時 kafka 自己內部的底層演算法和機制也可能導致資料丟失。

但是平時寫入資料遇到比較大的乙個問題,就是 leader 切換時可能導致資料丟失。所以本文僅僅是針對這個問題說了一下生產環境解決這個問題的方案。

hbase如何保證寫記憶體資料不丟失

寫wal,再寫memstore

mysql如何保證資料不丟失

兩階段提交,寫redlog,prepare,寫binlog,commit 

參考:

各種資料庫連線

mysql string driver com.mysql.jdbc.driver 驅動程式 string url jdbc mysql localhost 3306 db name 連線的url,db name為資料庫名 string username username 使用者名稱 string ...

各種資料庫連線

mysql string driver org.gjt.mm.mysql.driver 驅動程式 string url jdbc mysql localhost 3306 db name 連線的url,db name為資料庫名 string username username 使用者名稱 strin...

各種資料庫驅動

1 oracle8 8i 9i資料庫 thin模式 class.forname oracle.jdbc.driver.oracledriver newinstance string url jdbc oracle thin localhost 1521 orcl orcl為資料庫的sid strin...