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