cache和主從庫的數(shù)據(jù)不一致問題

總結(jié)自https://coolshell.cn/articles/17416.html

緩存和數(shù)據(jù)庫的同步機(jī)制,一般有幾種固定的套路。


程序自己保證一致性

程序中自己控制緩存和數(shù)據(jù)庫的更新過程,保證緩存的數(shù)據(jù)和數(shù)據(jù)庫保持一致。更新的時(shí)候,一般是通過控制更新和訪問緩存還有數(shù)據(jù)庫的順序。先更新數(shù)據(jù)庫,再將緩存設(shè)為實(shí)效,后續(xù)的讀請求再來更新緩存。

  • Cache Aside Pattern

由緩存服務(wù)保證一致性

通過一個(gè)緩存的服務(wù),使用緩存的應(yīng)用直接通過緩存去做數(shù)據(jù)操作,緩存和數(shù)據(jù)庫的數(shù)據(jù)一致性交給緩存服務(wù)內(nèi)部處理。緩存數(shù)據(jù)保證和數(shù)據(jù)庫一致性的機(jī)制,一般借鑒了操作系統(tǒng)同步緩存和內(nèi)存的機(jī)制:

  • Read/Write Through Pattern
  • Write Behind Caching Pattern

幾種機(jī)制的圖解

Cache Aside Pattern

Cache Aside Pattern 就是由調(diào)用方將新數(shù)據(jù)加載到cache。

sequenceDiagram
loop read data
application->>cache: try to read data from cache
cache->>application: not fount in the cache
application->>db: updata data from db to cache
db->>cache: update data in the cache
cache->>application: response data
end

loop write data
application->>db: update data in the db
db->>cache: invalid item in the cache
cache->>cache: waiting for next read request to reload the cache
end

不在更新數(shù)據(jù)庫后,繼續(xù)更新緩存中的數(shù)據(jù),是為了防止多線程更新的時(shí)候,向緩存中寫入臟數(shù)據(jù)。并為緩存設(shè)置失效時(shí)間。


Read Through Pattern

Read Through Pattern 就是在查詢中,由緩存服務(wù)自己將新數(shù)據(jù)加載到cache

sequenceDiagram
application->>cache service: read data from cache
cache service->>cache service: not hit
cache service->>db: read data from db
db->>cache service: updata data in the cache
cache service->>application: response data

Write Through Pattern

Write Through Pattern 就是在更新數(shù)據(jù)的時(shí)候:

  • 如果沒有命中,cache service將更新請求發(fā)給db,直接更新數(shù)據(jù)庫。
  • 如果命中,先更新cache,然后由cache service自己更新數(shù)據(jù)庫。
sequenceDiagram
loop not hit
application->>cache service: request update data
cache service->>cache service: not hit
cache service->>db: update data in the db
end

loop hit
application->>cache service: request update data
cache service->>cache service: hit item
cache service->>cache service: udpate data in the cache
cache service->>db: update data in the db
end

wiki上關(guān)于memery的一個(gè)活動(dòng)圖,可以作為Read/Write Through Pattern的實(shí)現(xiàn)參考

graph TD
A[Memory request] --> B{Request type}
B --> |Read| C[Cache hit?]
C --> |No| E[Locate a cache block to use]
E --> F[Read data from lower memory into the cache block]
F --> G[Return data]
G --> H[Done]
C --> |Yes| G

B --> |Write| D[Cache hit?]
D --> |No| I[Write data into lower memory]
I --> H
D --> |Yes| J[Write data into cache block]
J --> I

Write Behind Caching Pattern

Write Back套路,一句說就是,在更新數(shù)據(jù)的時(shí)候,只更新緩存,不更新數(shù)據(jù)庫,而我們的緩存會(huì)異步地批量更新數(shù)據(jù)庫。
wiki上的活動(dòng)圖以供參考

graph TD
MEM[Memory request] --> RT[Request type]
RT --> |Read| Read{Cache hit?}
Read --> |No| RLocate[Locate a cache block to use]
RLocate --> RDirty{Is it dirty?}
RDirty --> |No| R2C[Read data from lower memory into the cache block]
RDirty --> |Yes| R2M[Write cache block previouse data back to the lower memory]
R2M --> R2C
R2C --> MND[Mark the cache block as 'not dirty']
MND --> RE[Return data]
Read --> |Yes| RE
RE --> DONE

RT --> |Write| Write{Cache hit}
Write --> |No| WLocate[Locate a cache block to use]
WLocate --> WDirty{Is it dirty}
WDirty --> |No| W2C[Read data from lower memory into the cache block]
WDirty --> |Yes| W2M[Write cache block previouse data back to the lower memory]
W2M --> W2C
W2C --> WN2C[Write the new data into the cache block]
WN2C --> MD[Mark the cache block as 'dirty']
Write --> WN2C
MD --> DONE
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 理論總結(jié) 它要解決什么樣的問題? 數(shù)據(jù)的訪問、存取、計(jì)算太慢、太不穩(wěn)定、太消耗資源,同時(shí),這樣的操作存在重復(fù)性。因...
    jiangmo閱讀 3,139評論 0 11
  • Load data on demand into a cache from a data store. This ...
    jorgensen閱讀 5,311評論 0 2
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,554評論 19 139
  • 緣起 看到好些人在寫更新緩存數(shù)據(jù)代碼時(shí),先刪除緩存,然后再更新數(shù)據(jù)庫,而后續(xù)的操作會(huì)把數(shù)據(jù)再裝載的緩存中。然而,這...
    jiangmo閱讀 380評論 0 0

友情鏈接更多精彩內(nèi)容