redis怎么保證數(shù)據(jù)一致性

一般來說,只要你用到了緩存,不管是redis還是memcache,就可能會涉及到數(shù)據(jù)庫緩存與數(shù)據(jù)的一致性問題,這里我們以redis為例。

redis怎么保證數(shù)據(jù)一致性

我們該如何保證Redis與數(shù)據(jù)庫的一致性呢?

?So easy:? ? ? ? ? ? ? ? ? (推薦學習:Redis視頻教程

更新的時候,先更新數(shù)據(jù)庫,然后再刪除緩存。

讀的時候,先讀緩存;如果沒有的話,就讀數(shù)據(jù)庫,同時將數(shù)據(jù)放入緩存,并返回響應。

乍一看,一致性問題貌似很好的得到了解決。但仔細一想,你會發(fā)現(xiàn)還是有問題:如果先更新了數(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ù)庫,同時將數(shù)據(jù)放入緩存,并返回響應。

到這里是不是問題就得到了徹底的解決了呢?

其實并沒有,在高并發(fā)的場景下,會出現(xiàn)這樣的情況:數(shù)據(jù)發(fā)生了變更,先刪除了緩存,然后去修改數(shù)據(jù)庫。此時還沒來得及修改,一個請求過來了,去讀緩存,發(fā)現(xiàn)緩存空了,去讀數(shù)據(jù)庫,讀到了準備修改前的舊數(shù)據(jù),并且把舊數(shù)據(jù)放到了緩存。

隨后,數(shù)據(jù)變更程序完成了數(shù)據(jù)庫的修改。那么完了,這個時候發(fā)生數(shù)據(jù)不一致了……

redis怎么保證數(shù)據(jù)一致性解決方案:

針對這種情況,可以先把“修改DB”的操作放到一個jvm隊列,后面讀請求過來之后,“更新緩存”的操作也放進同一個JVM隊列,每個隊列,對于一個作業(yè)線程,按照隊列的順序,依次執(zhí)行相關(guān)操作,這樣就可以保證“更新緩存”一定是在DB修改之后,以保證數(shù)據(jù)一致性,具體如下圖所示:

redis怎么保證數(shù)據(jù)一致性

? 版權(quán)聲明
THE END
喜歡就支持一下吧
點贊6 分享