寫請求來了,要更新數據庫和緩存,一前一后更新,就可能導致緩存和DB中的數據在一段時間內不一致。
你只要用緩存,就可能會涉及到緩存與數據庫雙存儲雙寫,你只要是雙寫,就一定會有數據一致性的問題,那么你如何解決一致性問題?
一般來說,就是如果你的系統不是嚴格要求緩存+數據庫必須一致性的話,緩存可以稍微的跟數據庫偶爾有不一致的情況,
如果是強一致性,讀請求和寫請求串行化,串到一個內存隊列里去,這樣就可以保證一定不會出現不一致的情況(效率極低。)
串行化之后,就會導致系統的吞吐量會大幅度的降低,用比正常情況下多幾倍的機器去支撐線上的一個請求。
還有一種方式就是可能會暫時產生不一致的情況,但是發生的幾率特別小,就是先更新數據庫,然后再刪除緩存。
這種情況不存在並發問題么?
不是的。假設這會有兩個請求,一個請求A做查詢操作,一個請求B做更新操作,那么會有如下情形產生
(1)緩存剛好失效
(2)請求A查詢數據庫,得一個舊值
(3)請求B將新值寫入數據庫
(4)請求B刪除緩存
(5)請求A將查到的舊值寫入緩存
ok,如果發生上述情況,確實是會發生臟數據。
然而,發生這種情況的概率又有多少呢?
發生上述情況有一個先天性條件,就是步驟(3)的寫數據庫操作比步驟(2)的讀數據庫操作耗時更短,才有可能使得步驟(4)先於步驟(5)。可是,大家想想,數據庫的讀操作的速度遠快於寫操作的(不然做讀寫分離干嘛,做讀寫分離的意義就是因為讀操作比較快,耗資源少),因此步驟(3)耗時比步驟(2)更短,這一情形很難出現。
如何解決上述並發問題?
首先,給緩存設有效時間是一種方案。其次,采用異步延時刪除策略,保證讀請求完成以后,再進行刪除操作。