亚洲精品久久久久久第一页-人妻少妇精彩视品一区二区三区-91国产自拍免费视频-免费一级a在线播放视频正片-少妇天天日天天射天天爽-国产大屁股喷水视频在线观看-操美女骚穴抽插性爱视频-亚洲 欧美 中文字幕 丝袜-成人免费无码片在线观看

redis保證和數據庫事務一致 redis和mysql數據同步原理


redis保證和數據庫事務一致 redis和mysql數據同步原理

文章插圖
前言由于緩存的高并發(fā)和高性能已經在各種項目中被廣泛使用,在讀取緩存這方面基本都是一致的,大概都是按照下圖的流程進行操作:
但是在更新緩存方面,是更新完數據庫再更新緩存還是直接刪除緩存呢?又或者是先刪除緩存再更新數據庫?在這一點上就值得探討了 。
一致性方案在實際項目開發(fā)中需要保證數據庫和緩存中的數據一致,否則人家充值了100塊,不斷刷新卻還是顯示0.01元,豈不是尷尬?從理論上來說,為緩存設置過期時間是最終保證數據一致性的解決方案,采用這種方案的話,所有的寫操作都是以數據庫為準,如果數據庫寫入成功但是緩存更新失敗,只要緩存到過期時間之后后面讀緩存時自然會在數據庫中讀取新的值然后更新緩存 。接下來探討的思路主要的方向是在不依賴為緩存設置過期時間的前提下如何保證數據一致性 。這里主要探討三種方案:
①先更新數據庫,再更新緩存
②先刪除緩存,再更新數據庫
③先更新數據庫,再刪除緩存
先更新數據庫再更新緩存這種方案是普遍被反對的(在我的認知范圍中~),為啥呢?為啥這種方案就被反對呢?原因主要有兩方面,請聽我細細道來:
首先從數據安全方面考慮,如果同時有請求A和請求B同時進行操作,A先更新了數據庫的一條數據,隨后B馬上有更新了該條數據,但是可能因為網絡延遲等原因,B卻比A先更新了緩存,就會出現一種什么情況呢?緩存中的數據并不最新的B更新過的數據,就導致了數據不一致的情況 。
其次從業(yè)務場景方面考慮,如果是一個寫數據庫較多而讀數據庫較少的業(yè)務,如果采用這種方案就會導致數據還沒讀緩存就會被頻繁更新,白白浪費性能 。
綜合以上兩方面的考慮,這種方案果斷pass 。下面的兩種方案就是爭議較大的兩種方案了,到底是先刪緩存再更新數據庫還是先更新數據庫再刪除緩存?
先刪緩存再更新數據庫如果同時有一個請求A進行更新操作,請求B進行查詢操作,就可能會出現A請求進行寫操作前會刪除緩存,B請求剛好此時進來發(fā)現緩存是空的,B請求就會查詢數據庫,如果此時A請求的寫操作還未完成,B請求查詢到的就還是舊的值,還是會將舊的值寫入緩存,A請求將新的值寫入數據庫,此時就會導致數據不一致的問題,如果不采用給緩存設置過期時間的策略,該數據永遠都是臟數據 。
解決這種情況可以采用延時雙刪的策略,就是在更新數據庫之前先刪除緩存,然后對數據庫進行寫入操作,數據庫更新完成之后再次進行刪除緩存的操作,目的是刪除讀請求可能造成的緩存臟數據,第二次刪除緩存之前可以休眠幾秒,具體時間開發(fā)者可以評估一下自己項目讀數據業(yè)務邏輯的耗時,然后在該耗時基礎上加幾百ms即可,這么做的目的就是確保讀請求結束寫請求可以刪除讀請求造成的臟數據 。如果MySQL采用的是讀寫分離的架構,可能由于主從延時的原因造成數據不一致,可以在寫操作完成之后根據主從延時時間休眠一下然后再進行刪除緩存的操作 。延時雙刪的偽代碼如下:
# 偽代碼def delay_delete():redis.delete('name')# 更新數據庫之前先刪除緩存sql = 'update info set name='lili' where id=1;'# 更新數據庫cursor.execute(sql)time.sleep(1)# 如果mysql是主從架構則休眠主從延時的時間再多幾百msredis.delete('name')# 再次刪除緩存復制代碼那會不會存在第二次刪除緩存失敗的情況呢?如果第二次刪除失敗,還是會造成緩存和數據庫不一致的問題,又如何解決呢?且看下一種方案 。


以上關于本文的內容,僅作參考!溫馨提示:如遇健康、疾病相關的問題,請您及時就醫(yī)或請專業(yè)人士給予相關指導!

「愛刨根生活網」www.malaban59.cn小編還為您精選了以下內容,希望對您有所幫助: