redis和mysql数据不一致_高并发下为什么 redis 和数据库不一致?怎么解决?
現在的web架構一般都用redis作為緩存層來減輕數據庫的壓力,數據在此架構下的讀取問題,一般都是先判斷redis緩存是否有數據,如果有,直接返回,否則讀取數據庫的數據,寫入redis,返回數據,這是大致的讀取流程。
那么為什么會出現redis和數據庫不一致的問題呢?舉個例子,如果你的緩存里現在緩存了用戶的年齡的數據,每次用戶訪問的時候,如果緩存里有這個數據,直接返回,那么如果用戶更新了自己的年齡,你的操作步驟是什么?
先更新(刪除)redis緩存,再更新數據庫
先更新數據庫,再更新(刪除)用戶緩存
上面兩種不同的操作順序,不論哪種方法,理論上如果兩個步驟都成功了,那沒問題,如果一個更新成功了,另一個更新失敗了,那么就會導致數據庫和緩存不一致的問題,這就要求操作必須具備原子性,不論誰先執行,只要一個步驟出現錯誤,就因該回滾,誰都不能成功。
更新緩存or刪除緩存
這里簡單說下,更新緩存可能要消耗更多的cpu資源,所以建議直接刪除緩存。
舉個例子:緩存money=100,數據庫money=100,現在要求money=99
下面討論并發下兩種策略可能帶來的問題
先刪除緩存成功,后更新數據庫失敗
線程A刪除緩存,更新數據庫money中,還沒更新完
線程B過來發現緩存沒有了,去數據庫讀取,讀到的money=100
線程B,將讀到的money=100寫入緩存,現在緩存中的money=100
線程A將數據庫的money更新完成,money=99
最終redis緩存的數據是100,數據庫是99
適合原子性要求高的,不適合高并發
造成這個問題的原因就是線程A還沒干完事情,線程B就插進來了。解決這個問題的辦法,就是串行化,讓操作順序執行,不能交替進行。順序應該是刪除、更新、讀取。
先更新數據庫,再刪除緩存
線程A過來查數據,緩存沒有數據,讀取數據庫money=100
線程B更新數據庫money=99,并刪除緩存
線程A把讀到的money=100,寫到緩存里
最終redis緩存是100,數據庫是99
適合高并發,不適合原子性高的
造成這個問題的原因就是第二步驟,其實緩存并不存在,刪除是沒有用的,應該等到A把緩存寫入之后,再嘗試刪除緩存,這時候建議再第二步驟一直嘗試刪除緩存,知道刪除成功。
總結
以上是生活随笔為你收集整理的redis和mysql数据不一致_高并发下为什么 redis 和数据库不一致?怎么解决?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 网站访问量怎么刷_基于爬虫刷新某网站访问
- 下一篇: linux cmake编译源码,linu