溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

MySQL數據怎么同步到Redis緩存

發(fā)布時間:2023-03-16 11:33:58 來源:億速云 閱讀:160 作者:iii 欄目:開發(fā)技術

這篇“MySQL數據怎么同步到Redis緩存”文章的知識點大部分人都不太理解,所以小編給大家總結了以下內容,內容詳細,步驟清晰,具有一定的借鑒價值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來看看這篇“MySQL數據怎么同步到Redis緩存”文章吧。

1 Mysql查完數據,再同步寫入到Redis中

缺點1:會對接口造成延遲,因為同步寫入redis本身就有延遲,并且還要做重試,如果redis寫入失敗,還需要重試,那就更費時間了。

缺點2:不解耦,如果redis崩了,那直接卡線程了

缺點3:如果人為該數據庫,那就沒法同步了, 除非再人為刪除對應的Redis,但刪除Redis這個過程也有個時間差

2 Mysql查完數據,通過發(fā)送MQ,在消費者線程去同步Redis

缺點1:多了層MQ,也就是會有很大的概率導致同步延遲問題.

缺點2:要對MQ的可用性做預防

缺點3:如果人為該數據庫,那就沒法同步了

優(yōu)點1:可以大幅減少接口的延遲返回的問題

優(yōu)點2:MQ本身有重試機制,無需人工去寫重試代碼

優(yōu)點3:解耦,把查詢Mysql和同步Redis完全分離,互不干擾

3 訂閱Mysql的Binlog文件(可借助Canal來進行)

CanalServer會偽裝成MysqlServer從庫,去訂閱MysqlServer主庫的Binlog文件

Canal啟動的時候會配置對應的消息MQ(RabbitMQ, RocketMQ, Kafka), 監(jiān)聽到Binlog文件有變化是,會把變化的sql語句轉換成json格式,并作為消息內容發(fā)送到MQ中

項目中只要監(jiān)聽對應MQ,就能拿到Binlog改動的內容,Json數據中有明確的操作類型(CURD), 以及對應的數據。把對應數據同步到redis即可

缺點1:canal訂閱Binlog的整個操作過程是單線程的,所以面臨超高并發(fā)的情況下,性能可能不太出色。當然可以部署多個Canal 與 多個消費者,但是要注意消息重復消費問題,做好冪等性校驗

優(yōu)點1:即使人為改數據庫,也會監(jiān)聽到,并且也會同步

優(yōu)點2:異步同步,不會對接口返回有格外延遲

4 延遲雙刪

在執(zhí)行修改sql之前,先將redis的數據刪除

執(zhí)行更新sql

延遲一段時間

再次刪除redis的數據

// 延遲雙刪偽代碼
deleteRedisCache(key);   // 刪除redis緩存
updateMysqlSql(obj);        // 更新mysql
Thread.sleep(100);           // 延遲一段時間
deleteRedisCache(key);   // 再次刪除該key的緩存

缺點:這個延遲時間不好把控,到底延遲多久,這個很難去評估

擴展: 如果不使用延遲雙刪,僅僅是delete緩存,然后改mysql數據。只有這兩步會出現(xiàn)什么問題呢?

5. 單個請求,單線程沒問題,高并發(fā)多線程下會出問題

6. 如果Thread1線程要更新數據,此時Thread1線程把redis清理了

7. 此時Thread2線程來了,但Thread1還沒有更新mysql完畢

8. Thread2查詢redis肯定是null,此時Thread2就要查mysql了,然后再把查到的數據寫到緩存

9. 由于Thread1還沒來得及修改mysql數據,所以此時Thread2查出來的數據是【舊數據】,Thread2把舊數據又寫入Redis 了

10. 此時Thread3線程來了,查詢Redis發(fā)現(xiàn)有數據,則直接拿緩存數據了,此時【Thread3查出來的是舊數據】,直接帶著舊數據返回了,這就是問題所在

11. 而延遲雙刪的第二次刪除作用就是防止Thread2把舊數據又寫入了,有了延遲雙刪,Thread3查詢Redis的時候還是null,就會從mysql 去拿最新數據了

12. 所以正常的這個延遲時間,應該是Thread2查緩存到拿mysql數據,到再保存到redis這整個時間,作為Thread1的延遲時間,但是這個Thread2這個過程的時間會受到很多因素影響,因此很難斷定究竟會是多久

5 延遲雙寫

// 延遲雙寫偽代碼
updateMysqlSql(obj);        // 更新mysql
addRedis(key);   // 再次刪除該key的緩存

上述代碼缺陷;

  • 高并發(fā)下,兩條線程同時執(zhí)行上面代碼,并對mysql 修改,且修改內容不通,可能會導致Redis與Mysql數據不一致

  • T1線程執(zhí)行完updateMysqlSql,釋放了行鎖,此時T2線程再執(zhí)行updateMysqlSql 與 addRedis, 最后T1執(zhí)行addRedis,這種情況會導致數據庫改成了T2線程的數據,但Redis卻是T1線程的數據

優(yōu)化

// 完美延遲雙寫偽代碼
開啟事務
updateMysqlSql(obj);        // 更新mysql
addRedis(key);   // 再次刪除該key的緩存
提交事務

上述代碼改正:

把兩句代碼放到一個事務里面,只有T1執(zhí)行完Mysql 與 Redis的時候,T2才能開始執(zhí)行,就可以保證數據一致性。推薦使用分布式鎖

雙寫缺點:Mysql 與 Redis是單線程的。性能方面不行,因此不推薦使用

以上就是關于“MySQL數據怎么同步到Redis緩存”這篇文章的內容,相信大家都有了一定的了解,希望小編分享的內容對大家有幫助,若想了解更多相關的知識內容,請關注億速云行業(yè)資訊頻道。

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI