一般來說,只要你用到了緩存,不管是Redis還是memcache,就可能會涉及到資料庫快取與資料的一致性問題,這裡我們以Redis為例。
我們該如何保證Redis與資料庫的一致性呢?
So easy: (建議學習:Redis視訊教學)
更新的時候,先更新資料庫,然後刪除快取。
讀取的時候,先讀快取;如果沒有的話,就讀資料庫,同時將資料放入緩存,並回傳回應。
乍一看,一致性問題似乎很好的得到了解決。但仔細一想,你會發現還是有問題:如果先更新了資料庫,刪除快取的時候就失敗了怎麼辦?那麼資料庫中是新數據,快取中是老數據,數據出現不一致了。
改進方案:
先刪除緩存,然後再更新資料庫。因為即使後面更新資料庫失敗了,快取是空的,讀的時候會從資料庫重新拉,雖然都是舊數據,但數據是一致的。
所以方案就變成了:
更新的時候,先刪除緩存,然後再更新資料庫。
讀取的時候,先讀快取;如果沒有的話,就讀資料庫,同時將資料放入緩存,並回傳回應。
到這裡是不是問題就得到了徹底的解決了呢?
其實並沒有,在高並發的場景下,會出現這樣的情況:資料發生了變更,先刪除了緩存,然後去修改資料庫。此時還來不及修改,一個請求過來了,去讀緩存,發現緩存空了,去讀數據庫,讀到了準備修改前的舊數據,並且把舊數據放到了緩存。
隨後,資料變更程式完成了資料庫的修改。那麼完了,這個時候發生資料不一致了......
解決方案:
針對這種情況,可以先把「修改DB 」的操作放到一個JVM隊列,後面讀請求過來之後,「更新快取」的操作也放進同一個JVM隊列,每個隊列,對於一個作業線程,按照隊列的順序,依次執行相關操作,這樣就可以保證「更新快取」一定是在DB修改之後,以確保資料一致性,具體如下圖所示:
以上是redis怎麼保證資料一致性的詳細內容。更多資訊請關注PHP中文網其他相關文章!