2019-10-11如何保證Redis和數(shù)據(jù)庫雙寫一致性

為什么使用Redis

項(xiàng)目中使用Redis,主要考慮性能并發(fā)。如果僅僅是分布式鎖這些,完全可以用中間件ZooKeeper等代替。

性能:

如下圖所示,在大并發(fā)的情況下,所有的請(qǐng)求直接訪問數(shù)據(jù)庫,數(shù)據(jù)庫會(huì)出現(xiàn)連接異常。這個(gè)時(shí)候,就需要使用Redis做一個(gè)緩沖操作,讓請(qǐng)求先訪問到Redis,而不是直接訪問數(shù)據(jù)庫。

根據(jù)交互效果的不同,響應(yīng)時(shí)間沒有固定標(biāo)準(zhǔn)。在理想狀態(tài)下,我們的頁面跳轉(zhuǎn)需要在瞬間解決,對(duì)于頁內(nèi)操作則需要在剎那間解決。

并發(fā):

如下圖所示,在大并發(fā)的情況下,所有的請(qǐng)求直接訪問數(shù)據(jù)庫,數(shù)據(jù)庫會(huì)出現(xiàn)連接異常。這個(gè)時(shí)候,就需要使用Redis做一個(gè)緩沖操作,讓請(qǐng)求先訪問到Redis,而不是直接訪問數(shù)據(jù)庫。

2、使用Redis有什么缺點(diǎn)?

緩存和數(shù)據(jù)庫雙寫一致性問題

緩存雪崩問題

緩存擊穿問題

緩存的并發(fā)競(jìng)爭(zhēng)問題

3、單線程的Redis為什么這么快?

你知道Redis是單線程工作模型嗎?

純內(nèi)存操作

單線程操作,避免了頻繁的上下文切換

采用了非阻塞I/O多路復(fù)用機(jī)制

4、Redis的數(shù)據(jù)類型及使用場(chǎng)景

(這5種類型你用到過幾個(gè)?)

String:一般做一些復(fù)雜的計(jì)數(shù)功能的緩存;

Hash:單點(diǎn)登錄;

List:做簡(jiǎn)單的消息隊(duì)列的功能;

Set:做全局去重的功能;

SortedSet:做排行榜應(yīng)用,取TOPN操作;延時(shí)任務(wù);做范圍查找。

5、Redis過期策略和內(nèi)存淘汰機(jī)制?

正解:Redis采用的是定期刪除+惰性刪除策略。

為什么不用定時(shí)刪除策略?定期刪除+惰性刪除是如何工作的呢?采用定期刪除+惰性刪除就沒其他問題了么?

6、Redis和數(shù)據(jù)庫雙寫一致性問題

(最終一致性和強(qiáng)一致性)

如果對(duì)數(shù)據(jù)有強(qiáng)一致性要求,不能放緩存。

7、如何應(yīng)對(duì)緩存穿透和緩存雪崩問題

緩存穿透:即黑客故意去請(qǐng)求緩存中不存在的數(shù)據(jù),導(dǎo)致所有的請(qǐng)求都懟到數(shù)據(jù)庫上,從而數(shù)據(jù)庫連接異常。

緩存雪崩:即緩存同一時(shí)間大面積的失效,這個(gè)時(shí)候又來了一波請(qǐng)求,結(jié)果請(qǐng)求都懟到數(shù)據(jù)庫上,從而導(dǎo)致數(shù)據(jù)庫連接異常。

中小型的公司一般遇不到這些問題,但是大并發(fā)的項(xiàng)目,流量有幾百萬左右,這兩個(gè)問題一定要深刻考慮。

8、如何解決Redis并發(fā)競(jìng)爭(zhēng)Key問題?

這個(gè)問題大致就是,同時(shí)有多個(gè)子系統(tǒng)去set一個(gè)key。不太推薦使用redis的事務(wù)機(jī)制。

(1)如果對(duì)這個(gè)key操作,不要求順序

這種情況下,準(zhǔn)備一個(gè)分布式鎖,大家去搶鎖,搶到鎖就做set操作即可。

(2)如果對(duì)這個(gè)key操作,要求順序

假設(shè)有一個(gè)key1,系統(tǒng)A需要將key1設(shè)置為valueA,系統(tǒng)B需要將key1設(shè)置為valueB,系統(tǒng)C需要將key1設(shè)置為valueC.

期望按照key1的value值按照 valueA-->valueB-->valueC的順序變化。這種時(shí)候我們?cè)跀?shù)據(jù)寫入數(shù)據(jù)庫的時(shí)候,需要保存一個(gè)時(shí)間戳。假設(shè)時(shí)間戳如下

系統(tǒng)A key 1 {valueA 3:00}

系統(tǒng)B key 1 {valueB 3:05}

系統(tǒng)C key 1 {valueC 3:10}

那么,假設(shè)這會(huì)系統(tǒng)B先搶到鎖,將key1設(shè)置為{valueB 3:05}。接下來系統(tǒng)A搶到鎖,發(fā)現(xiàn)自己的valueA的時(shí)間戳早于緩存中的時(shí)間戳,那就不做set操作了。以此類推。

其他方法,比如利用隊(duì)列,將set方法變成串行訪問也可以??傊?,靈活變通。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容