W3Cschool
恭喜您成為首批注冊用戶
獲得88經(jīng)驗值獎勵
本文主要討論這么幾個問題:
(1)數(shù)據(jù)庫主從延時為何會導(dǎo)致緩存數(shù)據(jù)不一致
(2)優(yōu)化思路與方案
上一篇《緩存架構(gòu)設(shè)計細節(jié)二三事》中有一個小優(yōu)化點,在只有主庫時,通過“串行化”的思路可以解決緩存與數(shù)據(jù)庫中數(shù)據(jù)不一致。引發(fā)大家熱烈討論的點是“在主從同步,讀寫分離的數(shù)據(jù)庫架構(gòu)下,有可能出現(xiàn)臟數(shù)據(jù)入緩存的情況,此時串行化方案不再適用了”,這就是本文要討論的主題。
為什么會讀到臟數(shù)據(jù),有這么幾種情況:
(1)單庫情況下,服務(wù)層的并發(fā)讀寫,緩存與數(shù)據(jù)庫的操作交叉進行
雖然只有一個DB,在上述詭異異常時序下,也可能臟數(shù)據(jù)入緩存:
1)請求A發(fā)起一個寫操作,第一步淘汰了cache,然后這個請求因為各種原因在服務(wù)層卡住了(進行大量的業(yè)務(wù)邏輯計算,例如計算了1秒鐘),如上圖步驟1
2)請求B發(fā)起一個讀操作,讀cache,cache miss,如上圖步驟2
3)請求B繼續(xù)讀DB,讀出來一個臟數(shù)據(jù),然后臟數(shù)據(jù)入cache,如上圖步驟3
4)請求A卡了很久后終于寫數(shù)據(jù)庫了,寫入了最新的數(shù)據(jù),如上圖步驟4
這種情況雖然少見,但理論上是存在的, 后發(fā)起的請求B在先發(fā)起的請求A中間完成了。
(2)主從同步,讀寫分離的情況下,讀從庫讀到舊數(shù)據(jù)
在數(shù)據(jù)庫架構(gòu)做了一主多從,讀寫分離時,更多的臟數(shù)據(jù)入緩存是下面這種情況:
1)請求A發(fā)起一個寫操作,第一步淘汰了cache,如上圖步驟1
2)請求A寫數(shù)據(jù)庫了,寫入了最新的數(shù)據(jù),如上圖步驟2
3)請求B發(fā)起一個讀操作,讀cache,cache miss,如上圖步驟3
4)請求B繼續(xù)讀DB,讀的是從庫,此時主從同步還沒有完成,讀出來一個臟數(shù)據(jù),然后臟數(shù)據(jù)入cache,如上圖步4
5)最后數(shù)據(jù)庫的主從同步完成了,如上圖步驟5
這種情況請求A和請求B的時序是完全沒有問題的,是主動同步的時延(假設(shè)延時1秒鐘)中間有讀請求讀從庫讀到臟數(shù)據(jù)導(dǎo)致的不一致。
有同學(xué)說“那能不能先操作數(shù)據(jù)庫,再淘汰緩存”,這個是不行的,在《緩存架構(gòu)設(shè)計細節(jié)二三事》的文章中介紹過。
出現(xiàn)不一致的根本原因:
(1)單庫情況下,服務(wù)層在進行1s的邏輯計算過程中,可能讀到舊數(shù)據(jù)入緩存
(2)主從庫+讀寫分離情況下,在1s鐘主從同步延時過程中,可能讀到舊數(shù)據(jù)入緩存
既然舊數(shù)據(jù)就是在那1s的間隙中入緩存的,是不是可以在寫請求完成后,再休眠1s,再次淘汰緩存,就能將這1s內(nèi)寫入的臟數(shù)據(jù)再次淘汰掉呢?
答案是可以的。
寫請求的步驟由2步升級為3步:
(1)先淘汰緩存
(2)再寫數(shù)據(jù)庫(這兩步和原來一樣)
(3)休眠1秒,再次淘汰緩存
這樣的話,1秒內(nèi)有臟數(shù)據(jù)如緩存,也會被再次淘汰掉,但帶來的問題是:
(1)所有的寫請求都阻塞了1秒,大大降低了寫請求的吞吐量,增長了處理時間,業(yè)務(wù)上是接受不了的
寫請求由2步升級為2.5步:
(1)先淘汰緩存
(2)再寫數(shù)據(jù)庫(這兩步和原來一樣)
(2.5)不再休眠1s,而是往消息總線esb發(fā)送一個消息,發(fā)送完成之后馬上就能返回
這樣的話,寫請求的處理時間幾乎沒有增加,這個方法淘汰了緩存兩次,因此被稱為“緩存雙淘汰”法。這個方法付出的代價是,緩存會增加1次cache miss(代價幾乎可以忽略)。
提問:為什么上文總是說1s,這個1s是怎么來的?
回答:1s只是一個舉例,需要根據(jù)業(yè)務(wù)的數(shù)據(jù)量與并發(fā)量,觀察主從同步的時延來設(shè)定這個值。例如主從同步的時延為200ms,這個異步淘汰cache設(shè)置為258ms就是OK的。
在“異常時序”或者“讀從庫”導(dǎo)致臟數(shù)據(jù)入緩存時,可以用二次異步淘汰的“緩存雙淘汰”法來解決緩存與數(shù)據(jù)庫中數(shù)據(jù)不一致的問題,具體實施至少有三種方案:
(1)timer異步淘汰(本文沒有細講,本質(zhì)就是起個線程專門異步二次淘汰緩存)
(2)總線異步淘汰
(3)讀binlog異步淘汰
Copyright©2021 w3cschool編程獅|閩ICP備15016281號-3|閩公網(wǎng)安備35020302033924號
違法和不良信息舉報電話:173-0602-2364|舉報郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號
聯(lián)系方式:
更多建議: