溫馨提示×

溫馨提示×

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

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

實(shí)現(xiàn)Redis緩存和數(shù)據(jù)庫的數(shù)據(jù)一致性的方法

發(fā)布時間:2021-09-28 09:26:44 來源:億速云 閱讀:386 作者:iii 欄目:開發(fā)技術(shù)

本篇內(nèi)容主要講解“實(shí)現(xiàn)Redis緩存和數(shù)據(jù)庫的數(shù)據(jù)一致性的方法”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實(shí)用性強(qiáng)。下面就讓小編來帶大家學(xué)習(xí)“實(shí)現(xiàn)Redis緩存和數(shù)據(jù)庫的數(shù)據(jù)一致性的方法”吧!

目錄
  • 一、一致性

    • 1、強(qiáng)一致性

    • 2、弱一致性

    • 3、最終一致性

  • 二、redis緩存和mysql數(shù)據(jù)庫數(shù)據(jù)一致性解決

    • 1、方案一:采用延時雙刪策略

    • 2、方案二:一步更新緩存(基于訂閱Binlog的同步機(jī)制)

首先,我們先來看看有哪幾種一致性的情況呢?

一、一致性

1、強(qiáng)一致性

如果你的項(xiàng)目對緩存的要求是強(qiáng)一致性的,那么請不要使用緩存。這種一致性級別是最符合用戶直覺的,它要求系統(tǒng)寫入什么,讀出來的也會是什么,用戶體驗(yàn)好,但實(shí)現(xiàn)起來往往對系統(tǒng)的性能影響大。

2、弱一致性

這種一致性級別約束了系統(tǒng)在寫入成功后,不承諾立即可以讀到寫入的值,也不承諾多久之后數(shù)據(jù)能夠達(dá)到一致,但會盡可能地保證到某個時間級別(比如秒級別)后,數(shù)據(jù)能夠達(dá)到一致狀態(tài)。

3、最終一致性

最終一致性是弱一致性的一個特例,系統(tǒng)會保證在一定時間內(nèi),能夠達(dá)到一個數(shù)據(jù)一致的狀態(tài)。這里之所以將最終一致性單獨(dú)提出來,是因?yàn)樗侨跻恢滦灾蟹浅M瞥绲囊环N一致性模型,也是業(yè)界在大型分布式系統(tǒng)的數(shù)據(jù)一致性上比較推崇的模型。一般情況下,高可用只確保最終一致性,不確保強(qiáng)一致性。

強(qiáng)一致性,讀請求和寫請求會串行化,串到一個內(nèi)存隊(duì)列里去,這樣會大大增加系統(tǒng)的處理效率,吞吐量也會大大降低。

二、redis緩存和mysql數(shù)據(jù)庫數(shù)據(jù)一致性解決

實(shí)現(xiàn)Redis緩存和數(shù)據(jù)庫的數(shù)據(jù)一致性的方法

這張圖,大多數(shù)人的很多業(yè)務(wù)操作都是根據(jù)這個圖來做緩存的。但是一旦設(shè)計到雙寫或者
數(shù)據(jù)庫和緩存更新等操作,就很容易出現(xiàn)數(shù)據(jù)一致性的問題。無論是先寫數(shù)據(jù)庫,在刪除緩存,還是先刪除緩存,在寫入數(shù)據(jù)庫,都會出現(xiàn)數(shù)據(jù)一致性的問題。列舉兩個小例子。

1、 先刪除了redis緩存,但是因?yàn)槠渌裁丛蜻€沒來得及寫入數(shù)據(jù)庫,另外一個線程就來讀取,發(fā)現(xiàn)緩存為空,則去數(shù)據(jù)庫讀取到之前的數(shù)據(jù)并寫入緩存,此時緩存中為臟數(shù)據(jù)。

2、 如果先寫入了數(shù)據(jù)庫,但是在緩存被刪除前,寫入數(shù)據(jù)庫的線程因?yàn)槠渌虮恢袛嗔?,沒有刪除掉緩存,就也會出現(xiàn)數(shù)據(jù)不一致的情況。

總的來說,寫和讀在多數(shù)情況下都是并發(fā)的,不能絕對保證先后順序,就會很容易出現(xiàn)緩存和數(shù)據(jù)庫數(shù)據(jù)不一致的情況,還怎么解決呢?

1、方案一:采用延時雙刪策略

基本思路: 在寫庫前后都進(jìn)行刪除緩存操作,并且設(shè)置合理的超時時間
基本步驟: 先刪除緩存–再寫數(shù)據(jù)庫—休眠一段時間—再次刪除緩存
注:休眠的時間是根據(jù)自己的項(xiàng)目的讀數(shù)據(jù)業(yè)務(wù)邏輯的耗時來確定的。這樣做主要是為了保證在寫請求之前確保讀請求結(jié)束,寫請求可以刪除讀請求造成的緩存臟數(shù)據(jù)。

該方案的弊端: 集合雙刪策略+緩存超時策略設(shè)置,這樣最差的結(jié)果就是在超時時間內(nèi)數(shù)據(jù)存在不一致,又增加了寫請求的耗時。

2、方案二:一步更新緩存(基于訂閱Binlog的同步機(jī)制)

基本思路: mysql Binlog增強(qiáng)訂閱消費(fèi)+消息隊(duì)列+增量數(shù)據(jù)更新到redis—讀redis:熱數(shù)據(jù)基本上都在redis—寫mysql:增刪改都是操作mysql—更新redis數(shù)據(jù):mysql的數(shù)據(jù)操作Binlog,來更新redis

我們再來看看詳細(xì)的過程

1、Redis更新

1)、數(shù)據(jù)操作主要分為兩大塊:
一個是全量,將全部數(shù)據(jù)寫去redis;另一個就是增量(update、insert、delete),實(shí)時更新。

2)、讀取binlog后分析 ,利用消息隊(duì)列,推送更新各臺的redis緩存數(shù)據(jù)。
這樣一旦MySQL中產(chǎn)生了新的寫入、更新、刪除等操作,就可以把binlog相關(guān)的消息推送至Redis,Redis再根據(jù)binlog中的記錄,對Redis進(jìn)行更新。
其實(shí)這種機(jī)制,很類似MySQL的主從備份機(jī)制,因?yàn)镸ySQL的主備也是通過binlog來實(shí)現(xiàn)的數(shù)據(jù)一致性。

這里可以結(jié)合使用canal(阿里的一款開源框架),通過該框架可以對MySQL的binlog進(jìn)行訂閱,而canal正是模仿了mysql的slave數(shù)據(jù)庫的備份請求,使得Redis的數(shù)據(jù)更新達(dá)到了相同的效果。

當(dāng)然,這里的消息推送工具你也可以采用別的第三方:kafka、rabbitMQ等來實(shí)現(xiàn)推送更新Redis。

到此,相信大家對“實(shí)現(xiàn)Redis緩存和數(shù)據(jù)庫的數(shù)據(jù)一致性的方法”有了更深的了解,不妨來實(shí)際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!

向AI問一下細(xì)節(jié)

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

AI