mysql資料相乘 快取資料庫一致性

2021-10-12 21:09:48 字數 2326 閱讀 6049

為什麼這個專題名字是叫方案,個人經驗覺得,方案是需要針對業務特點而定製的,沒有絕對的好壞,只有是否適合。

例如,對應快取資料庫如果要嚴格的一致性,能不能做到? 能做到,但是架構複雜度和成本很高。甚至維護保證一致性架構導致中帶來的bug可能都比快取資料庫不一致導致的bug多。

而且我自己在業務中,也不是用的最完美方案,但是也能低成本的滿足業務需求。當然了,能滿足了業務不代表不用去深入研究。當我們在用不完美方案時,一定要知道不完美方案可能導致的問題。並且監控問題,在問題達到需要解決程度時,能夠及時優化公升級。

個人覺得,方案要避免過度設計,方案是隨著業務增長而變化的,針對這個快取資料庫的方案。可能是這麼變化的。

初期,訪問量不大,業務直接訪問資料庫即可。最基礎的一主一從,也能支援估計2000qps的查詢併發。

當業務量增大時,峰值qps可能上萬,就引入redis做一層快取,這個時候如果請求讀為主,就需要考慮最基礎的快取資料庫一致性了。

業務繼續增大,比如redis開始集群,mysql開始集群,就需要開始考慮更加複雜的保障快取資料庫一致性方案了。因為這個時候就需要考慮mysql,redis可用性,快取穿透等等複雜場景了。

技術方案是跟著業務特點不斷衍化的,所以沒有不好的方案,只有最適合的。

方案的差別主要在於資料庫和快取的操作順序

讀: 先讀快取資料,沒有讀到就查資料庫,並且寫入快取

寫: 先刪除快取,然後再更新資料庫

理想情況是:

寫入新資料後,清理快取,然後等下一次讀到這個資料,就重新從資料庫中寫入到快取。

這個方案造成的不一致性概率比較大,例如:

a執行緒在寫資料keya,程序剛剛執行完刪除快取keya,這個時候b執行緒讀取keya,然後寫入快取,然後這時a執行緒才完成資料庫更新。

這個時候就會導致b執行緒讀入舊資料,導致寫入了髒資料到快取。

為什麼說不一致概率比較大,因為一般業務中讀的qps會遠遠大於寫的,在寫資料庫的時候,出現讀請求的概率還是有的。

但是即使這麼多缺點,目前業務中我還是用的這個方法。介紹完方案二后,在說下我的思路。

cache aside pattern 這個是比較常用的模式,facebook推薦

讀: 先讀快取資料,沒有讀到就查資料庫,並且寫入快取

寫: 先寫資料庫,成功後,再讓快取失效

上面會導致資料庫不一致的情況:

a執行緒讀操作,沒有命中快取,到資料庫中取資料,b執行緒寫操作,寫完資料庫後,讓快取失效,a執行緒把老的資料存入,導致髒資料。

這種情況出現概率比較低: 需要發生在讀快取時快取失效,而且併發著有乙個寫操作。

寫的qps會比較低,在讀快取失效的時候寫概率更低。至少比方案一出現概率低很多。

來看看為什麼我使用的可能會出問題的方案一。

這個需要結合下業務背景,從實際業務出發。

背景:後端環境,併發比較高,dba對資料庫訪問qps有比較嚴格的控制,整體穩定性比較好,redis扛高併發,穩定性相對dba差。

業務上高併發沒有明顯集中的熱key,redis的讀取比較均勻,同乙個key被併發讀概率不大。

基於背景1,方案二有個點需要考慮:

寫時,寫資料庫成功,刪除快取失敗怎麼處理。

處理:需要刪除快取失敗重試,重試失敗就需要回滾資料庫操作。萬一回滾資料庫失敗怎麼辦。

有人說redis加上重試,基於概率相乘,概率及其小,其實實際情況不會是簡單相乘,這個時候,可能網路抖動,可能訪問例項cpu滿了等等,重試能成功的概率有限。

而這個在方案一中就比較好處理:

寫資料時:

刪快取失敗,業務報錯。

刪快取成功,寫資料庫失敗,業務報錯

刪快取成功,寫資料庫成功,請求成功

整個流程業務處理比較簡單。業務報錯,對於使用者就是需要重試,但是不至於導致髒資料。

如文章前面提到,方案一還是有概率出問題,我們不能止步於此。如果監控到線上有髒資料,我們還需要上加強修復方案

讀: 先讀快取資料,沒有讀到就查資料庫,並且寫入快取

寫: 先刪除快取,然後再更新資料庫, 延遲(例如100ms)刪除快取

plus版加了一步,寫時: 延遲100ms刪除快取

這樣是為了保證把讀到的髒資料清洗掉。

有人會問,延遲刪除快取失敗怎麼辦,我認為方案沒有百分百的,這個刪除是乙個保險操作,能大概率的降低髒資料。

這裡的失敗和方案二的失敗有本質區別,方案二失敗,必然導致髒資料。而這裡的功能是減少出錯概率的。

我們可以試著考慮下,如果涉及到熱key, 針對方案二如何優化。

其實方案二我覺得比較核心的問題是,寫庫成功後,刪快取失敗的場景。這個時候,可以考慮把失敗的快取放到乙個隊裡中,或者啟動乙個執行緒處理失敗的情況,再那裡保證快取的刪除成功率。

github和giteestar (#^.^#),提issue。更多總結mysql、redis、網路程式設計

MySQL資料庫快取

原文 mysql 資料庫快取cache功能總結 mysql cache功能分析 1 mysql的cache功能的key的生成原理是 把select語句按照一定的hash規則生成唯一的key,select的結果生成value,即 key value。所以對於cache而言,select語句是區分大小寫...

mysql資料庫快取

開啟mysql查詢快取的方案 1.在my.cnf中新增如下配置並重啟,開啟mysql快取 query cache size 256m query cache limit 10m query cache type 1 query cache size為總快取大小,官方推薦不要超過256m query ...

資料庫快取資料

那麼咱們要用的就是資料庫進行快取 那麼就要建立乙個資料庫 public class myhelper extends sqliteopenhelper override public void oncreate sqlitedatabase sqlitedatabase override publi...