redis和mysql实现原理_redis和mysql结合数据一致性方案
緩存讀:
緩存由于高并發高性能,已經被廣泛的應用。在讀取緩存方面做法一致。流程如下:
寫緩存:
1.先更新數據庫,再更新緩存
2.先更新數據庫,再刪除緩存。
(1).先更新數據庫,再更新緩存
這套方案,基本不推薦使用。
原因一:(線程安全角度)同時請求A和請求B進行更新操作,會出現。
(1)線程A更新了數據庫
(2)線程B更新了數據庫
(3)線程B更新了緩存
(4)線程A更新了緩存
由于網絡原因出現A更新緩存比B慢,這就導致了臟數據,因此不考慮。
原因二:(業務場景)
(1)如果你是一個寫數據庫場景比較多,而讀數據場景比較少的業務需求,采用這種方案就會導致,數據壓根還沒讀到,緩存就被頻繁的更新,浪費性能。
(2)如果你寫入數據庫的值,并不是直接寫入緩存的,而是要經過一系列復雜的計算再寫入緩存。那么,每次寫入數據庫后,都再次計算寫入緩存的值,無疑是浪費性能的。顯然,刪除緩存更為適合。
總結:不建議使用該種 解決方案。
(2).先更新數據庫,再更新緩存
方案存在的問題?
假設有兩個請求,一個請求A做查詢操作,一個請求B做更新操作。會有如下情況發生:
緩存剛好失效
請求A查詢數據庫,得到一個舊值
請求B將新值寫入數據庫
請求B刪除緩存
請求A將查詢的舊值寫入緩存ok
如上情況,會發生臟數據。
在數據庫做讀寫分離的情況下,如果出現網絡延遲,寫庫同步讀庫的時候,另外一個線程讀取讀庫舊數據,就會對發生臟數據。
如何解決?
采用延時雙刪模式:
先淘汰緩存
再修改數據庫
休眠1(n)秒,再次淘汰緩存,可以將由于網絡問題造成的緩存臟數據再次刪除。
延遲1秒會造成整體吞吐量降低,可以采用異步方式處理。
如果第二次刪除,刪除失敗怎么辦?
提供重試機制
消息隊列異步補償機制:
如果覺得如上方案對代碼的侵入性太大,可以代用如下方案。
訂閱mysql的binlog日志:
訂閱mysql的binlog程序有現成的中間件canal。
參考:https://zhuanlan.zhihu.com/p/59167071
原文:https://www.cnblogs.com/wingfirefly/p/14419728.html
總結
以上是生活随笔為你收集整理的redis和mysql实现原理_redis和mysql结合数据一致性方案的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python win32库与subpro
- 下一篇: ebs和java哪个前景好_EBS与实例