緩存與數(shù)據(jù)庫雙寫時的數(shù)據(jù)一致性

參考:
如何保證緩存與數(shù)據(jù)庫的雙寫一致性条舔?

一般來說枫耳,如果允許緩存可以稍微的跟數(shù)據(jù)庫偶爾有不一致的情況,也就是說如果你的系統(tǒng)不是嚴格要求 “緩存+數(shù)據(jù)庫” 必須保持一致性的話孟抗,最好不要做這個方案迁杨,即:讀請求和寫請求串行化,串到一個內(nèi)存隊列里去凄硼。
串行化可以保證一定不會出現(xiàn)不一致的情況铅协,但是它也會導致系統(tǒng)的吞吐量大幅度降低,用比正常情況下多幾倍的機器去支撐線上的一個請求摊沉。

1.Cache Aside Pattern

最經(jīng)典的緩存+數(shù)據(jù)庫讀寫的模式狐史,就是 Cache Aside Pattern。

  • 讀的時候说墨,先讀緩存骏全,緩存沒有的話,就讀數(shù)據(jù)庫尼斧,然后取出數(shù)據(jù)后放入緩存姜贡,同時返回響應。
  • 更新的時候棺棵,先更新數(shù)據(jù)庫鲁豪,然后再刪除緩存潘悼。

A.為什么是刪除緩存,而不是更新緩存爬橡?

原因很簡單治唤,很多時候,在復雜點的緩存場景糙申,緩存不單單是數(shù)據(jù)庫中直接取出來的值宾添。比如可能更新了某個表的一個字段,然后其對應的緩存柜裸,是需要查詢另外兩個表的數(shù)據(jù)并進行運算缕陕,才能計算出緩存最新的值的。
另外更新緩存的代價有時候是很高的疙挺。每次修改數(shù)據(jù)庫的時候扛邑,都一定要將其對應的緩存更新一份?這個緩存到底會不會被頻繁訪問到铐然?

其實刪除緩存蔬崩,而不是更新緩存,就是一個 lazy 計算的思想搀暑,不要每次都重新做復雜的計算沥阳,不管它會不會用到,而是讓它到需要被使用的時候再重新計算自点。像 mybatis桐罕,hibernate,都有懶加載思想桂敛。

2.最初級的緩存不一致問題及解決方案

先更新數(shù)據(jù)庫功炮,再刪除緩存。如果刪除緩存失敗了术唬,那么會導致數(shù)據(jù)庫中是新數(shù)據(jù)薪伏,緩存中是舊數(shù)據(jù),數(shù)據(jù)就出現(xiàn)了不一致碴开。

解決思路:
先刪除緩存毅该,再更新數(shù)據(jù)庫博秫。如果數(shù)據(jù)庫更新失敗了潦牛,那么數(shù)據(jù)庫中是舊數(shù)據(jù),緩存中是空的挡育,那么數(shù)據(jù)不會不一致巴碗。
因為讀的時候緩存沒有,所以去讀了數(shù)據(jù)庫中的舊數(shù)據(jù)即寒,然后更新到緩存中橡淆。

3.比較復雜的數(shù)據(jù)不一致問題分析

數(shù)據(jù)發(fā)生了變更召噩,先刪除了緩存,然后要去修改數(shù)據(jù)庫逸爵,此時還沒修改具滴。一個請求過來,去讀緩存师倔,發(fā)現(xiàn)緩存空了构韵,去查詢數(shù)據(jù)庫,查到了修改前的舊數(shù)據(jù)趋艘,放到了緩存中疲恢。隨后數(shù)據(jù)變更的程序完成了數(shù)據(jù)庫的修改。完了瓷胧,數(shù)據(jù)庫和緩存中的數(shù)據(jù)不一樣了...

A.為什么上億流量高并發(fā)場景下显拳,緩存會出現(xiàn)這個問題?

只有在對一個數(shù)據(jù)在并發(fā)的進行讀寫的時候搓萧,才可能會出現(xiàn)這種問題杂数。如果并發(fā)量很低的情況下,不會出現(xiàn)剛才描述的那種不一致的場景矛绘。
如果每天的是上億的流量耍休,每秒并發(fā)讀是幾萬,每秒只要有數(shù)據(jù)更新的請求货矮,就可能會出現(xiàn)上述的數(shù)據(jù)庫+緩存不一致的情況羊精。

B.解決方案如下:

更新數(shù)據(jù)的時候,根據(jù)數(shù)據(jù)的唯一標識囚玫,將操作路由之后喧锦,發(fā)送到一個 jvm 內(nèi)部隊列中。讀取數(shù)據(jù)的時候抓督,如果發(fā)現(xiàn)數(shù)據(jù)不在緩存中燃少,那么將重新執(zhí)行“讀取數(shù)據(jù)+更新緩存”的操作,根據(jù)唯一標識路由之后铃在,也發(fā)送到同一個 jvm 內(nèi)部隊列中阵具。
一個隊列對應一個工作線程,每個工作線程串行拿到對應的操作定铜,然后一條一條的執(zhí)行阳液。這樣的話,一個數(shù)據(jù)變更的操作揣炕,先刪除緩存帘皿,然后再去更新數(shù)據(jù)庫,但是還沒完成更新畸陡。此時如果一個讀請求過來鹰溜,沒有讀到緩存虽填,那么可以先將緩存更新的請求發(fā)送到隊列中,此時會在隊列中積壓曹动,然后同步等待緩存更新完成斋日。
這里有一個優(yōu)化點,一個隊列中墓陈,其實多個更新緩存請求串在一起是沒意義的桑驱,因此可以做過濾,如果發(fā)現(xiàn)隊列中已經(jīng)有一個更新緩存的請求了跛蛋,那么就不用再放個更新請求操作進去了熬的,直接等待前面的更新操作請求完成即可。
待那個隊列對應的工作線程完成了上一個操作的數(shù)據(jù)庫的修改之后赊级,才會去執(zhí)行下一個操作押框,也就是緩存更新的操作,此時會從數(shù)據(jù)庫中讀取最新的值理逊,然后寫入緩存中橡伞。
如果請求還在等待時間范圍內(nèi),不斷輪詢發(fā)現(xiàn)可以取到值了晋被,那么就直接返回兑徘;如果請求等待的時間超過一定時長,那么這一次直接從數(shù)據(jù)庫中讀取當前的舊值羡洛。

C.高并發(fā)的場景下挂脑,該解決方案要注意的問題:

m.讀請求長時阻塞

由于讀請求進行了非常輕度的異步化,所以一定要注意讀超時的問題欲侮,每個讀請求必須在超時時間范圍內(nèi)返回崭闲。
該解決方案,最大的風險點在于說威蕉,可能數(shù)據(jù)更新很頻繁刁俭,導致隊列中積壓了大量更新操作在里面,然后讀請求會發(fā)生大量的超時韧涨,最后導致大量的請求直接走數(shù)據(jù)庫牍戚。

m.讀請求并發(fā)量過高

突然間大量讀請求會在幾十毫秒的延時行在服務上,看服務能不能扛的住虑粥,需要多少機器才能扛住最大的極限情況的峰值如孝。

m.多服務實例部署的請求路由

可能這個服務部署了多個實例,那么必須保證說舀奶,執(zhí)行數(shù)據(jù)更新操作暑竟,以及執(zhí)行緩存更新操作的請求斋射,都通過 Nginx 服務器路由到相同的服務實例上育勺。

m.熱點商品的路由問題但荤,導致請求的傾斜

萬一某個商品的讀寫請求特別高,全部打到相同的機器的相同的隊列里面去了涧至,可能會造成某臺機器的壓力過大腹躁。就是說,因為只有在商品數(shù)據(jù)更新的時候才會清空緩存南蓬,然后才會導致讀寫并發(fā)纺非,所以其實要根據(jù)業(yè)務系統(tǒng)去看,如果更新頻率不是太高的話赘方,這個問題的影響并不是特別大烧颖,但是的確可能某些機器的負載會高一些。

?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末窄陡,一起剝皮案震驚了整個濱河市炕淮,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌跳夭,老刑警劉巖涂圆,帶你破解...
    沈念sama閱讀 211,265評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異币叹,居然都是意外死亡润歉,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,078評論 2 385
  • 文/潘曉璐 我一進店門颈抚,熙熙樓的掌柜王于貴愁眉苦臉地迎上來踩衩,“玉大人,你說我怎么就攤上這事贩汉【怕瑁” “怎么了?”我有些...
    開封第一講書人閱讀 156,852評論 0 347
  • 文/不壞的土叔 我叫張陵雾鬼,是天一觀的道長萌朱。 經(jīng)常有香客問我,道長策菜,這世上最難降的妖魔是什么晶疼? 我笑而不...
    開封第一講書人閱讀 56,408評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮又憨,結果婚禮上翠霍,老公的妹妹穿的比我還像新娘。我一直安慰自己蠢莺,他們只是感情好寒匙,可當我...
    茶點故事閱讀 65,445評論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般锄弱。 火紅的嫁衣襯著肌膚如雪考蕾。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,772評論 1 290
  • 那天会宪,我揣著相機與錄音肖卧,去河邊找鬼。 笑死掸鹅,一個胖子當著我的面吹牛塞帐,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播巍沙,決...
    沈念sama閱讀 38,921評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼葵姥,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了句携?” 一聲冷哼從身側響起牌里,我...
    開封第一講書人閱讀 37,688評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎务甥,沒想到半個月后牡辽,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,130評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡敞临,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,467評論 2 325
  • 正文 我和宋清朗相戀三年态辛,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片挺尿。...
    茶點故事閱讀 38,617評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖编矾,靈堂內(nèi)的尸體忽然破棺而出熟史,到底是詐尸還是另有隱情,我是刑警寧澤窄俏,帶...
    沈念sama閱讀 34,276評論 4 329
  • 正文 年R本政府宣布凹蜈,位于F島的核電站仰坦,受9級特大地震影響悄晃,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜庶近,卻給世界環(huán)境...
    茶點故事閱讀 39,882評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望拦盹。 院中可真熱鬧,春花似錦溪椎、人聲如沸普舆。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,740評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽沼侣。三九已至,卻和暖如春歉秫,著一層夾襖步出監(jiān)牢的瞬間蛾洛,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,967評論 1 265
  • 我被黑心中介騙來泰國打工雁芙, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留轧膘,地道東北人。 一個月前我還...
    沈念sama閱讀 46,315評論 2 360
  • 正文 我出身青樓兔甘,卻偏偏與公主長得像谎碍,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子洞焙,可洞房花燭夜當晚...
    茶點故事閱讀 43,486評論 2 348

推薦閱讀更多精彩內(nèi)容