Redis mysql 雙寫一致性

意思是 當數據庫數據更新時,redis中的緩存數據和數據庫中的數據怎麼保存一致;

 

第一種方案:先更新再刪除緩存。

缺點:先更新,其他線程來拿數據會產生髒數據,而且可能會重複闡述緩存

第二種方案: 先刪除緩存再更新。

缺點:刪除緩存之後,在更新期間如果其他線程要來取數據,發現緩存沒了,去數據庫取舊值,再更新到緩存裏面。這樣會產生髒數據,並且產生髒數據之後,之後取得一直是髒數據。

 

兩種方案比較 都有很大的缺陷,但是第二種方案可以改進,第一種方案沒法改進。

 

第二種方案改進版: 先刪除緩存,再更新,更新之後再刪除緩存。

採用兩次刪除緩存的機制,來避免第二種方案產生髒數據之後,之後取得的一直是髒數據的問題。該方法產生的髒數據只能是更新期間的髒數據。

缺點:更新期間還是會產生髒數據;第二次刪除可能不成功。

 

二次改進:採用消息隊列 把第二次刪除key的消息放到消息隊列,保證一定能刪除。

缺點:還是沒有改變,更新期間產生的髒數據.

 

最終方案:

當數據更新的時候,在緩存中保存一個更新的標誌位(類似於id),然後開始更新,當更新期間,其他線程過來拿數據,發現該數據處在更新階段,就加入一個隊列等待取數據,設置等待時間,期間隊列頭不斷輪詢數據是否更新完畢。如果在等待時間內數據沒有更新完畢,就拿緩存數據,如果數據更新完畢,就取新數據。

eg:數據更新完畢之後,更自己去更新緩存,等待的線程直接去拿緩存就ok

具體流程: A線程更新數據時,會在緩存數據上加一個表示位,表示該數據正在更新,B線程過來取值,發現標示位,設置等待時間進入隊列等待,不斷輪詢緩存,看標示位是否取消,如果期間A線程更新完畢,會更新緩存去除標示位,B線程輪詢到直接拿緩存;如果沒有更新完畢,就拿緩存中的舊值。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章