日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網(wǎng)為廣大站長(zhǎng)提供免費(fèi)收錄網(wǎng)站服務(wù),提交前請(qǐng)做好本站友鏈:【 網(wǎng)站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(wù)(50元/站),

點(diǎn)擊這里在線咨詢客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會(huì)員:747

在高并發(fā)的業(yè)務(wù)場(chǎng)景下,數(shù)據(jù)庫(kù)大多數(shù)情況都是用戶并發(fā)訪問(wèn)最薄弱的環(huán)節(jié)。所以,就需要使用redis做一個(gè)緩沖操作,讓請(qǐng)求先訪問(wèn)到redis,而不是直接訪問(wèn)MySQL等數(shù)據(jù)庫(kù)。

Redis緩存和MySQL數(shù)據(jù)一致性方案

 

這個(gè)業(yè)務(wù)場(chǎng)景,主要是解決讀數(shù)據(jù)從Redis緩存,一般都是按照下圖的流程來(lái)進(jìn)行業(yè)務(wù)操作。

Redis緩存和MySQL數(shù)據(jù)一致性方案

 

讀取緩存步驟一般沒有什么問(wèn)題,但是一旦涉及到數(shù)據(jù)更新:數(shù)據(jù)庫(kù)和緩存更新,就容易出現(xiàn)緩存(Redis)和數(shù)據(jù)庫(kù)(MySQL)間的數(shù)據(jù)一致性問(wèn)題

不管是先寫MySQL數(shù)據(jù)庫(kù),再刪除Redis緩存;還是先刪除緩存,再寫庫(kù),都有可能出現(xiàn)數(shù)據(jù)不一致的情況。舉一個(gè)例子:

1.如果刪除了緩存Redis,還沒有來(lái)得及寫庫(kù)MySQL,另一個(gè)線程就來(lái)讀取,發(fā)現(xiàn)緩存為空,則去數(shù)據(jù)庫(kù)中讀取數(shù)據(jù)寫入緩存,此時(shí)緩存中為臟數(shù)據(jù)。

2.如果先寫了庫(kù),在刪除緩存前,寫庫(kù)的線程宕機(jī)了,沒有刪除掉緩存,則也會(huì)出現(xiàn)數(shù)據(jù)不一致情況。

因?yàn)閷懞妥x是并發(fā)的,沒法保證順序,就會(huì)出現(xiàn)緩存和數(shù)據(jù)庫(kù)的數(shù)據(jù)不一致的問(wèn)題。

如來(lái)解決?這里給出兩個(gè)解決方案,先易后難,結(jié)合業(yè)務(wù)和技術(shù)代價(jià)選擇使用。

緩存和數(shù)據(jù)庫(kù)一致性解決方案

1.第一種方案:采用延時(shí)雙刪策略

在寫庫(kù)前后都進(jìn)行redis.del(key)操作,并且設(shè)定合理的超時(shí)時(shí)間。

偽代碼如下

public void write(String key,Object data){
 redis.delKey(key);
 db.updateData(data);
 Thread.sleep(500);
 redis.delKey(key);
 }

2.具體的步驟就是:

1)先刪除緩存

2)再寫數(shù)據(jù)庫(kù)

3)休眠300-500毫秒

4)再次刪除緩存

那么,這個(gè)500毫秒怎么確定的,具體該休眠多久呢?

需要評(píng)估自己的項(xiàng)目的讀數(shù)據(jù)業(yè)務(wù)邏輯的耗時(shí)。這么做的目的,就是確保讀請(qǐng)求結(jié)束,寫請(qǐng)求可以刪除讀請(qǐng)求造成的緩存臟數(shù)據(jù)。

當(dāng)然這種策略還要考慮redis和數(shù)據(jù)庫(kù)主從同步的耗時(shí)。最后的的寫數(shù)據(jù)的休眠時(shí)間:則在讀數(shù)據(jù)業(yè)務(wù)邏輯的耗時(shí)基礎(chǔ)上,加幾百ms即可。比如:休眠1秒。

3.設(shè)置緩存過(guò)期時(shí)間

從理論上來(lái)說(shuō),給緩存設(shè)置過(guò)期時(shí)間,是保證最終一致性的解決方案。所有的寫操作以數(shù)據(jù)庫(kù)為準(zhǔn),只要到達(dá)緩存過(guò)期時(shí)間,則后面的讀請(qǐng)求自然會(huì)從數(shù)據(jù)庫(kù)中讀取新值然后回填緩存。

4.該方案的弊端

結(jié)合雙刪策略+緩存超時(shí)設(shè)置,這樣最差的情況就是在超時(shí)時(shí)間內(nèi)數(shù)據(jù)存在不一致,而且又增加了寫請(qǐng)求的耗時(shí)。

2、第二種方案:異步更新緩存(基于訂閱binlog的同步機(jī)制)

1.技術(shù)整體思路:

MySQL binlog增量訂閱消費(fèi)+消息隊(duì)列+增量數(shù)據(jù)更新到redis

1)讀Redis:熱數(shù)據(jù)基本都在Redis

2)寫MySQL:增刪改都是操作MySQL

3)更新Redis數(shù)據(jù):MySQ的數(shù)據(jù)操作binlog,來(lái)更新到Redis

2.Redis更新

1)數(shù)據(jù)操作主要分為兩大塊:

  • 一個(gè)是全量(將全部數(shù)據(jù)一次寫入到redis)
  • 一個(gè)是增量(實(shí)時(shí)更新)

這里說(shuō)的是增量,指的是mysql的update、insert、delate變更數(shù)據(jù)。

2)讀取binlog后分析 ,利用消息隊(duì)列,推送更新各臺(tái)的redis緩存數(shù)據(jù)。

這樣一旦MySQL中產(chǎn)生了新的寫入、更新、刪除等操作,就可以把binlog相關(guān)的消息推送至Redis,Redis再根據(jù)binlog中的記錄,對(duì)Redis進(jìn)行更新。

其實(shí)這種機(jī)制,很類似MySQL的主從備份機(jī)制,因?yàn)镸ySQL的主備也是通過(guò)binlog來(lái)實(shí)現(xiàn)的數(shù)據(jù)一致性。

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

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

分享到:
標(biāo)簽:緩存 Redis
用戶無(wú)頭像

網(wǎng)友整理

注冊(cè)時(shí)間:

網(wǎng)站:5 個(gè)   小程序:0 個(gè)  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會(huì)員

趕快注冊(cè)賬號(hào),推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨(dú)大挑戰(zhàn)2018-06-03

數(shù)獨(dú)一種數(shù)學(xué)游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過(guò)答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫(kù),初中,高中,大學(xué)四六

運(yùn)動(dòng)步數(shù)有氧達(dá)人2018-06-03

記錄運(yùn)動(dòng)步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓(xùn)練成績(jī)?cè)u(píng)定2018-06-03

通用課目體育訓(xùn)練成績(jī)?cè)u(píng)定