面試題 系統中為什麼不推薦雙寫

2022-07-10 17:27:11 字數 2608 閱讀 3352

引言

某日,阿雄跑去面試!於是有如下情形

面試官:"阿雄是吧,做做自我介紹!"

阿 雄:"我叫阿雄,來自某a國際電商公司!"

面試官:"我看你專案裡用了elasticsearch,你是怎麼同步資料的呢?"

阿 雄:"在**裡寫入資料庫的時候,同時再寫入elasticsearch!"

面試官:"那你如何保證寫入資料庫,和寫入elasticsearch原子性問題呢?萬一寫入資料庫成功了,寫入elasticsearch失敗了怎麼處理?"

阿 雄:"我還是回去等通知吧!"

ok,以上情形純屬虛構,如有雷同,絕對巧合!

其實這篇文章所**的資料同步策略並不限於某兩種固定的儲存系統之間,而想去**一種通用的資料同步策略。主要分為以下三個部分

(1)背景介紹

(2)雙寫缺點

(3)改良方案

正文背景介紹

話說阿雄在加入某a國際電商公司的時候,業務系統十分簡單,乙個database就能搞定一切!

可是某a國際電商公司在產品韓的領導下,業務增長迅速,阿雄發現了資料庫越來越慢,於是乎阿雄加入了一些快取,如redis來快取一些資料,提高系統的響應能力。

又過了一段時間,產品韓發現搜尋的速度灰常慢,讓阿雄去改。阿雄在網上發現,現在業內都用一些elasticsearch做一些全文檢索的操作,於是乎阿雄將一些需要全文檢索的資料放入elasticsearch,提高了系統的搜尋能力!

隨著資料的膨脹,阿雄慢慢的發現了,對資料庫做一些資料分析操作,效能明顯的跟不上了。於是乎阿雄將資料庫裡的資料,匯入hadoop,然後進行資料分析。

(省略一萬字….)

最後,阿雄和產品韓幸福的在一起了。

ok,好,現在分析上面的場景!思考第乙個問題

1、在database,redis,elasticsearch,hadoop中的資料是有關係的,還是彼此獨立的?

顯然是有關係的,在這幾個資料來源中的資料都是相關的。只是格式不一樣而已!例如,對於一條product資料,在資料庫裡是

在redis裡就是key為 product:pid:1,value是

如上所示,只是資料格式不一樣而已!

那好,現在思考第二個問題

2、既然這些資料來源之間資料是相關的,如何保證這幾個資料來源之間資料一致性!

一種比較簡單且容易想到的方案是,hardcode在程式中

例如現在有兩個資料來源datasouce1和datasource2,我們往裡頭寫資料,**如下

productservice

}這就是我們標題中所提到的雙寫!那麼,雙寫會帶來什麼壞處呢?ok,繼續往下看!

雙寫缺點

一致性問題

打個比方我們現在有兩個client,同時往兩個datasouce寫資料。

乙個client往裡頭入x為1

乙個client往裡頭入x為5

那麼會有如下情形出現

如圖所示,兩個datasouce的資料就不一致了,乙個為1,乙個為5。除非接下來有乙個新的請求,對x資料發生了變更,才能修正這種現象!否則,你可能永遠都發現不了。

原子性問題

因為我們需要同時往datasource1和datasource2一起寫資料,你需要保證

x1. writedatasource1();

x2. writedatasource2();

這兩個操作一起成功,或者一起失敗!如果採用雙寫的方法,是避不開這個問題的!

那麼有沒有通用的辦法來解決這些問題呢?

有的,只要能按順序記錄資料的變更即可!那具體怎麼做呢,我們繼續往下看!

改良方案

在該架構下,所有的資料變更寫入乙個訊息佇列裡去。其他各資料來源從訊息佇列裡恢復資料即可!

那麼,此時還有一致性問題,和原子性問題麼?

一致性問題

ok,這種情況下,各個資料來源之間資料肯定是一致的。因為寫入順序已經在訊息佇列中定義好,各資料來源按照訊息佇列中的訊息順序,恢復資料即可,並不存在競爭現象。因此,不會出現不一致的問題!

原子性問題

ok,這種情況下,如果寫入datasource失敗會怎麼樣?例如出現了網路問題,這條訊息恢復失敗了。這個問題其實好解決,一般我們在順序根據訊息恢復資料的時候,會記錄下座標。如果寫入失敗,停止恢復資料。下次從該座標處恢復資料即可。

但是在上面那張圖中,寫入database是非同步寫入的。這樣就不符合很多業務場景的"寫後即讀"的要求,因此,在實際落地中,做了一些變更!通用做法是去提取資料庫的變化!

如下圖所示

在該圖中的中介軟體,例如oracle中的oracle golden gate可以提取資料變化。mysql中的canal能提取資料的變化。至於訊息佇列,可以選用kafka。直接提取資料變化到kafka中,其他資料來源從kafka中獲取資料,避免了直接雙寫從而導致一致性和原子性問題。

總結本問討論了在專案中常見的資料同步問題,希望大家有所收穫。

面試題 為什麼要使用訊息佇列?

其實面試官主要是想看看 為什麼使用訊息佇列?其實就是想知道是因為什麼原因引入的mq技術,為了解決哪些問題。面試官期望的回答就是,當初你們公司有乙個什麼樣的業務場景,這個場景有什麼樣的技術挑戰,不用mq可能會有麻煩,現在引入mq帶來了哪些好處。通過mq的好處是 解耦,非同步,削峰。解耦這個場景通常是發...

面試題 為什麼要分庫分表

為什麼要分表分庫 設計高併發系統的時候,資料庫層面該如何設計 使用過哪些分表分庫中介軟體?不同的分表分庫中介軟體都有什麼優點和缺點?你們是如何對具體的資料庫進行垂直拆分和水平拆分的?其實這一塊內容主要就是針對高併發的,因為分庫分表主要解決的問題就是支撐高並 資料量大兩個問題。而且現在如果是去網際網路...

作業系統面試題(更新中。。)

如果在乙個程序集合中,每個程序都在等待只能由該集合中的其他程序才能引發的事件,而無限期陷入僵持的局面成為死鎖。即一組程序中,如果每個程序都獲得了部分資源,還想要得到其他程序所占用的資源,最終所有的程序都將陷入死鎖。互斥條件 程序互斥使用資源 占有和等待條件 部分分配條件 申請新資源得不到滿足而等待時...