<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          淺談緩存模式

          共 1821字,需瀏覽 4分鐘

           ·

          2022-02-26 02:29

          緩存作為實際開發(fā)中高頻出現(xiàn)的基礎(chǔ)組件,這里簡單談?wù)勈褂镁彺娴膸追N典型模式

          abstract.jpeg

          Cache Aside Pattern

          Cache Aside模式,是我們?nèi)粘i_發(fā)中經(jīng)常使用的緩存模式。該模式的目的在于保證并發(fā)的前提下盡可能減少(緩存與數(shù)據(jù)庫間)數(shù)據(jù)不一致的可能,其是對AP模型下Base理論的體現(xiàn)。具體來說,在該模式下對于數(shù)據(jù)的讀操作,步驟如下:

          1. 首先從緩存中讀取數(shù)據(jù)
          2. 如果命中緩存Cache Hit,則直接進(jìn)入步驟4
          3. 如果未命中緩存Cache Miss,則從數(shù)據(jù)庫讀取數(shù)據(jù),并放入緩存中
          4. 返回數(shù)據(jù)結(jié)果

          而對于數(shù)據(jù)的寫操作,其步驟流程就很簡單了

          1. 更新數(shù)據(jù)庫,即將數(shù)據(jù)寫入數(shù)據(jù)庫
          2. 刪除緩存中相應(yīng)的數(shù)據(jù)

          顯然這里對于讀操作的流程步驟沒有什么爭議。問題在于寫操作中為什么是先寫數(shù)據(jù)庫、再刪緩存?能不能先刪除緩存再寫數(shù)據(jù)庫?答案顯然是不能。如下圖所示,當(dāng)寫操作剛刪除完緩存中的數(shù)據(jù)時,恰好此時有一個新的讀請求。其讀取數(shù)據(jù)庫,并設(shè)置緩存。此時緩存中Name的值為Aaron。然后寫操作開始寫數(shù)據(jù)庫,將數(shù)據(jù)庫中的Name修改為Bob。可以看到此時緩存與數(shù)據(jù)庫中的數(shù)據(jù)發(fā)生不一致

          figure 1.jpeg

          還有人可能會問,為什么在Cache Aside模式的寫操作過程中,為什么不在寫完數(shù)據(jù)庫后、再去寫緩存呢?這樣不是可以提高下一次讀操作的效率么?一方面,有些場景下計算緩存值的成本可能較高,如果本次寫緩存后。下次又是一次寫操作,則會浪費之前所計算的緩存。故緩存的寫入放在讀操作中進(jìn)行,即所謂的懶加載。另一方面,其同樣會導(dǎo)致數(shù)據(jù)的一致性問題。如下圖所示,有兩個請求分別進(jìn)行寫操作。當(dāng)寫操作#1剛剛寫完數(shù)據(jù)庫,此時DB中Age的值為22。此時另外一個寫操作#2則將數(shù)據(jù)庫、緩存均更新為18?,F(xiàn)在寫操作#1開始寫緩存,可以看到當(dāng)其操作結(jié)束后。數(shù)據(jù)庫、緩存中Age的值出現(xiàn)了不一致

          figure 2.png

          前面提到了Cache Aside模式只能盡可能地減少發(fā)生數(shù)據(jù)不一致的問題,其在極端情況下依然有可能會出現(xiàn)數(shù)據(jù)不一致。如下圖所示,比如在某請求在進(jìn)行讀操作時,緩存中并無相應(yīng)數(shù)據(jù)。造成該現(xiàn)象的原因有可能是因為此前剛剛完成了一次寫操作,把緩存刪掉了;也有可能是因為是第一次訪問,緩存無數(shù)據(jù)所導(dǎo)致的。總之該請求的讀操作需要從數(shù)據(jù)庫中讀取,這里記為200。這時突然有另外一個請求,即寫操作#2。其迅速完成了數(shù)據(jù)庫的寫入將其更新為300,并同時刪除了緩存。而此時讀操作才開始將其此前讀到的200寫入緩存。顯然此時緩存與數(shù)據(jù)庫的數(shù)據(jù)發(fā)生了不一致

          figure 3.jpeg

          甚至可以說,在數(shù)據(jù)庫使用主從架構(gòu)時,如果從庫的同步延遲較高,即雖然針對主庫的寫請求很快完成了寫數(shù)據(jù)庫、刪除緩存的操作;但此時從庫的數(shù)據(jù)依然還沒有被同步更新過來,導(dǎo)致對從庫的讀操作訪問到了舊值并回寫到了緩存當(dāng)中。此時同樣出現(xiàn)了數(shù)據(jù)的不一致性問題。故針對類似這種極端場景,可以考慮在基礎(chǔ)的Cache Aside(即寫數(shù)據(jù)庫、刪緩存)完成后,經(jīng)過一定的延遲時間后再進(jìn)行一次緩存刪除操作,以解決讀操作把舊值寫入緩存的問題。即所謂的「延遲雙刪」。當(dāng)然這里第二次刪除所需的延遲時間,需要根據(jù)實際業(yè)務(wù)場景來決策

          Read/Write Through Pattern

          在Cache Aside模式中,我們需要同時操作數(shù)據(jù)庫和緩存,以保持二者間數(shù)據(jù)的同步。而在Read/Write Through模式下,則簡單很多。我們只需對緩存服務(wù)進(jìn)行讀、寫即可。由緩存服務(wù)內(nèi)部實現(xiàn)與數(shù)據(jù)庫數(shù)據(jù)的同步。換言之,在該模式下可以將緩存服務(wù)視為數(shù)據(jù)庫的門面/代理。典型地,Ehcache支持該緩存模式

          Write Behind Pattern

          在Write Through模式中,當(dāng)進(jìn)行寫入操作時,緩存服務(wù)內(nèi)部是先寫入緩存、再同步到數(shù)據(jù)庫中。此舉顯然大大降低了性能,故提出了Write Behind模式,其不同點就在于。執(zhí)行寫操作時,緩存服務(wù)是先寫入緩存,然后通過異步的方式寫入數(shù)據(jù)庫。典型地,數(shù)據(jù)庫的Buffer Pool緩沖池中就使用了該緩存模式

          參考文獻(xiàn)

          1. 鳳凰架構(gòu): 構(gòu)建可靠的大型分布式系統(tǒng) 周志明著
          瀏覽 73
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  日本乱伦福利 | 免费A√在线播放 | www色7777 | 操操操操操操操操操逼 | 去干网69 |