天天看點

兩次被裁之後,我終于解決了資料庫緩存一緻性問題

作者:好奇德mR

今天是我的又一場面試,而且是大廠面試。我要一洗前恥,證明自己。

好了,我要趕緊出發,不然通往美好生活的996路公共汽車又堵了。

經曆過西二旗的人潮人湧之後,我按時來到了面試官面前。

和面試官寒暄了幾句,他直接問了一個技術問題

"如果網站流量太高,我們通常會加緩存來減輕資料庫壓力,讀緩存很簡單,如下圖

兩次被裁之後,我終于解決了資料庫緩存一緻性問題

關于寫緩存,你知道怎麼設計這個方案,保證緩存與資料庫的資料一緻性嗎?"

一刹那,往事湧上心頭,因為我在這個問題上,已經栽了兩次了。

第一次是在實習期。

那年二十,剛剛工作,每日如喽啰。

實習的公司是一家外包公司,沒有什麼技術規範,按時上線是大家最重要的諾言。

我的第一個任務就是增加緩存,降低Mysql的壓力。

這個任務最核心的就是寫緩存時怎麼保證緩存和資料庫的一緻性,當年還是實習生的我顯然沒有意識到這個需求的複雜性,直接采用的方案就是

先更新資料庫,再更新緩存

上線第二天,網站就出了Bug,我就被甲方爸爸投訴了。

後來,在複盤中我才發現,網站挂了的原因是:

如果同時有請求A和請求B進行更新操作,那麼會出現

兩次被裁之後,我終于解決了資料庫緩存一緻性問題

請求B是最後請求的,那麼應該是他最後更新緩存為正确的資料,但是有可能請求A處理的更慢,是以請求A更新了最後的緩存。

另外這個系統寫資料庫場景比較多,而讀請求比較少,這種方案就導緻資料壓根還沒讀到,緩存就被頻繁的更新,浪費性能。

然後我當天就被辭退了,理由是在辦公室工位吃螺蛳粉。

沒想到啊沒想到,在這個問題上,我還能梅開二度。

畢業之後進入的第一家公司,兢兢業業兩年半,業務量也逐漸上來了。

通路量上升,代表着我的薪水也有機會上升。我立馬做了個方案,準備在一向不看好我的經理面前表現一把。

核心邏輯就是采用

先删緩存,再更新資料庫

經理看完方案,直接畫了下面一個圖

兩次被裁之後,我終于解決了資料庫緩存一緻性問題

淡淡說道:"這樣的話,緩存都是髒資料了。"

我想了下,說:"确實,不過可以雙删緩存。"

public void write(String key,Object data){  
     redis.delKey(key); // 删緩存  
     db.updateData(data); //更新資料庫  
     Thread.sleep(1000); // 根據業務執行時間确定具體的時間  
     redis.delKey(key); // 我再删緩存  
 }  
           

經理笑了笑,說:"我們可是采用了MySQL讀寫分離架構啊,如果有下面這樣兩個請求

兩次被裁之後,我終于解決了資料庫緩存一緻性問題

還是會導緻資料不一緻啊!"

我有點不悅,這可是我主動加班做的方案,一句贊賞都沒有,怎麼老是被質疑?

但還是回答道 "那就sleep時間修改為業務執行時間+主從同步時間就可以了,就是等主從同步完了再删一次。"

經理又問道:"嗯,可以。不過你這樣删除緩存兩次,會造成吞吐量降低,怎麼辦?"

我覺得很不爽了,又不是他開發。算了,我回應到:"那就将第二次删除改為異步的。即重新起一個線程,異步删除。"

經理又問道:"那要是第二次删除緩存失敗呢?"

兩次被裁之後,我終于解決了資料庫緩存一緻性問題

我無奈了:"您說呢,畢竟您也是經理,要不您也說兩個方案讓我學習一下?"

經理笑了笑:"年輕人,路走窄了啊!"

然後我當天就被辭退了,理由是我代碼縮進用的Tab而非空格。

此刻,我坐在面試官前面,面對這個問題已經有三年了,我也早已胸有成竹。

想到這,我直接站了起來,走到白闆面前,說道:"實不相瞞,前兩次我的離職都和這個問題有關,是以我也思考了很多,不如直接我就講講最優解法。那就是

先更新資料庫,再删緩存

當然,這樣也會有并發問題,比如

兩次被裁之後,我終于解決了資料庫緩存一緻性問題

但是資料庫讀操作速度遠快于寫操作,是以存在髒資料的可能性為0。

當然如果您問,如果真的存在怎麼辦?

簡單,雙删就行了,即第一次删除緩存之後,等待一段時間重新再删一次。

當然您如果還問,删除緩存失敗了怎麼辦,解決方法如下

兩次被裁之後,我終于解決了資料庫緩存一緻性問題

即引入消息隊列,删除緩存失敗的記錄下來重複删除,直到成功方可。如此一來,萬無一失。"

面試官點了點頭,鼓了鼓掌,歎到:"優秀,不過我好奇你前兩次的離職,可以和我講講嗎?"

面試官聽完我的經曆之後,對我深表同情,問道:"假如我給了你offer,你走到之前那些開除你的人面前,你會說什麼呢?"

我走到窗戶旁邊,望向遠方,輕聲道:"我會走到他們面前,把offer甩給他們看,告訴他們,我等了三年,就是要等一個機會,我要争一口氣,不是想證明我了不起,我隻是要告訴人家,我失去的東西一定要拿回來!"

繼續閱讀