偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

Redis數(shù)據(jù)一致性問(wèn)題的三種解決方案

數(shù)據(jù)庫(kù) Redis
緩存由于其高并發(fā)和高性能的特性,已經(jīng)在項(xiàng)目中被廣泛使用。在讀取緩存方面,大家沒(méi)啥疑問(wèn),都是按照下圖的流程來(lái)進(jìn)行業(yè)務(wù)操作。

1、首先Redis是什么

Redis(Remote Dictionary Server ),是一個(gè)高性能的基于Key-Value結(jié)構(gòu)存儲(chǔ)的NoSQL開(kāi)源數(shù)據(jù)庫(kù)。大部分公司采用Redis來(lái)實(shí)現(xiàn)分布式緩存,用來(lái)提高數(shù)據(jù)查詢(xún)效率。

2、為什么會(huì)選Redis

在Web應(yīng)用發(fā)展的初期,系統(tǒng)的訪(fǎng)問(wèn)和并發(fā)并不高,交互也比較少。但隨著業(yè)務(wù)的擴(kuò)大,訪(fǎng)問(wèn)量的提升,使得服務(wù)器負(fù)載和關(guān)系型數(shù)據(jù)庫(kù)出現(xiàn)瓶頸,而導(dǎo)致瓶頸的源頭,主要體現(xiàn)在磁盤(pán)IO上。隨著互聯(lián)網(wǎng)的進(jìn)一步發(fā)展,對(duì)系統(tǒng)性能有了更高的要求,Redis的出現(xiàn),解決了很多問(wèn)題。至于我們?yōu)槭裁匆x擇Redis,我總結(jié)為以下六個(gè)原因:

1)、基于內(nèi)存存儲(chǔ),可以降低對(duì)關(guān)系型數(shù)據(jù)庫(kù)的訪(fǎng)問(wèn)頻次,從而緩解數(shù)據(jù)庫(kù)壓力

2)、數(shù)據(jù)IO操作能支持更高級(jí)別的QPS,官方發(fā)布的指標(biāo)是10W;

3)、提供了比較多的數(shù)據(jù)存儲(chǔ)結(jié)構(gòu),比如string、list、hash、set、zset等等。

4)、采用單線(xiàn)程實(shí)現(xiàn)IO操作,避免了并發(fā)情況下的線(xiàn)程安全問(wèn)題。

5)、可以支持?jǐn)?shù)據(jù)持久化,避免因服務(wù)器故障導(dǎo)致數(shù)據(jù)丟失的問(wèn)題

6)、Redis還提供了更多高級(jí)功能,比如分布式鎖、分布式隊(duì)列、排行榜、查找附近的人等功能,為更復(fù)雜的需求提供了成熟的解決方案。

3、 應(yīng)用場(chǎng)景

緩存,作為Key-Value形態(tài)的內(nèi)存數(shù)據(jù)庫(kù),Redis 最先會(huì)被想到的應(yīng)用場(chǎng)景便是作為數(shù)據(jù)緩存

分布式鎖,分布式環(huán)境下對(duì)資源加鎖

分布式共享數(shù)據(jù),在多個(gè)應(yīng)用之間共享

排行榜,自帶排序的數(shù)據(jù)結(jié)構(gòu)(zset)

消息隊(duì)列,pub/sub功能也可以用作發(fā)布者 / 訂閱者模型的消息

4、Redis用作緩存時(shí)

4.1、作為緩存使用流程

緩存由于其高并發(fā)和高性能的特性,已經(jīng)在項(xiàng)目中被廣泛使用。在讀取緩存方面,大家沒(méi)啥疑問(wèn),都是按照下圖的流程來(lái)進(jìn)行業(yè)務(wù)操作。

4.2、數(shù)據(jù)性一致性問(wèn)題

例如我們使用Redis來(lái)作為緩存時(shí),讓請(qǐng)求先訪(fǎng)問(wèn)到Redis,而不是直接訪(fǎng)問(wèn)數(shù)據(jù)庫(kù)。而在這種業(yè)務(wù)場(chǎng)景下,可能會(huì)出現(xiàn)緩存和數(shù)據(jù)庫(kù)數(shù)據(jù)不一致性的問(wèn)題。

在更新的時(shí)候,操作緩存和數(shù)據(jù)庫(kù)無(wú)疑就是以下四種可能之一:

  • 先更新緩存,再更新數(shù)據(jù)庫(kù)
  • 先更新數(shù)據(jù)庫(kù),再更新緩存
  • 先刪除緩存,再更新數(shù)據(jù)庫(kù)
  • 先更新數(shù)據(jù)庫(kù),再刪除緩存

4.2.1、先更新緩存,再更新數(shù)據(jù)庫(kù)

如果我成功更新了緩存,但是在執(zhí)行更新數(shù)據(jù)庫(kù)的那一步,服務(wù)器突然宕機(jī)了,那么此時(shí),我的緩存中是最新的數(shù)據(jù),而數(shù)據(jù)庫(kù)中是舊的數(shù)據(jù)。

臟數(shù)據(jù)就因此誕生了,并且如果我緩存的信息(是單獨(dú)某張表的),而且這張表也在其他表的關(guān)聯(lián)查詢(xún)中,那么其他表關(guān)聯(lián)查詢(xún)出來(lái)的數(shù)據(jù)也是臟數(shù)據(jù),結(jié)果就是直接會(huì)產(chǎn)生一系列的問(wèn)題。

4.2.2、先更新數(shù)據(jù)庫(kù),在更新緩存

只有等到緩存過(guò)期之后,才能訪(fǎng)問(wèn)到正確的信息。那么在緩存沒(méi)過(guò)期的時(shí)間段內(nèi),所看到的都是臟數(shù)據(jù)。

以上兩圖中只要執(zhí)行第二步時(shí)失敗了,就必然會(huì)產(chǎn)生臟數(shù)據(jù)。

4.2.3、先刪除緩存,在更新數(shù)據(jù)庫(kù)

這種方式在沒(méi)有高并發(fā)的情況下,是可能保持?jǐn)?shù)據(jù)一致性的。

如果只有第一步執(zhí)行成功,而第二步失敗,那么只有緩存中的數(shù)據(jù)被刪除了,但是數(shù)據(jù)庫(kù)沒(méi)有更新,那么在下一次進(jìn)行查詢(xún)的時(shí)候,查不到緩存,只能重新查詢(xún)數(shù)據(jù)庫(kù),構(gòu)建緩存,這樣其實(shí)也是相對(duì)做到了數(shù)據(jù)一致性。

但如果是處于讀寫(xiě)并發(fā)的情況下,還是會(huì)出現(xiàn)數(shù)據(jù)不一致的情況:

執(zhí)行完成后,明顯可以看出,1號(hào)用戶(hù)所構(gòu)建的緩存,并不是最新的數(shù)據(jù),還是存在問(wèn)題的

4.2.4、先更新數(shù)據(jù)庫(kù),在刪除緩存

如果更新數(shù)據(jù)庫(kù)成功了,而刪除緩存失敗了,那么數(shù)據(jù)庫(kù)中就會(huì)是新數(shù)據(jù),而緩存中是舊數(shù)據(jù),數(shù)據(jù)就出現(xiàn)了不一致情況。

和之前一樣,如果兩段代碼都執(zhí)行成功,在并發(fā)情況下會(huì)是什么樣呢?

還是會(huì)造成數(shù)據(jù)的不一致性。

但是此處達(dá)成這個(gè)數(shù)據(jù)不一致性的條件明顯會(huì)比起其他的方式更為困難 :

  • 時(shí)刻1:讀請(qǐng)求的時(shí)候,緩存正好過(guò)期
  • 時(shí)刻2:讀請(qǐng)求在寫(xiě)請(qǐng)求更新數(shù)據(jù)庫(kù)之前查詢(xún)數(shù)據(jù)庫(kù),
  • 時(shí)刻3:寫(xiě)請(qǐng)求,在更新數(shù)據(jù)庫(kù)之后,要在讀請(qǐng)求成功寫(xiě)入緩存前,先執(zhí)行刪除緩存操作。

這通常是很難做到的,因?yàn)樵谡嬲牟l(fā)開(kāi)發(fā)中,更新數(shù)據(jù)庫(kù)是需要加鎖的,不然沒(méi)一點(diǎn)安全性~

一定程度上來(lái)講,這種方式還是解決了一定程度上的數(shù)據(jù)不一致性問(wèn)題的。

4.3、總結(jié)

以上四種方式無(wú)論選擇那種方式,如果實(shí)在多服務(wù)或時(shí)并發(fā)的情況下,其實(shí)都是有可能產(chǎn)生數(shù)據(jù)不一致性的。

為了解決這個(gè)存在的問(wèn)題有以下方式:

4.3.1、延遲雙刪

先進(jìn)行緩存清除,再執(zhí)行update,最后(延遲N秒)再執(zhí)行緩存清除。進(jìn)行兩次刪除,且中間需要延遲一段時(shí)間

public void write(String key,Object data){
// 延遲雙刪偽代碼
		deleteRedisCache(key);   // 刪除redis緩存
		updateMysqlSql(obj);        // 更新mysql
		Thread.sleep(100);           // 延遲一段時(shí)間
		deleteRedisCache(key);   // 再次刪除該key的緩存
}

延遲雙刪的流程圖:

解決這樣的問(wèn)題,其實(shí)最好的方式就是在執(zhí)行完更新數(shù)據(jù)庫(kù)的操作后,先休眠一會(huì)兒,再進(jìn)行一次緩存的刪除,以確保數(shù)據(jù)一致性

首先延遲刪除的時(shí)間需要大于 1號(hào)用戶(hù)執(zhí)行流程的總時(shí)間

就是1號(hào)用戶(hù)從數(shù)據(jù)庫(kù)讀取數(shù)據(jù) 寫(xiě)入緩存時(shí)間

4.3.2、通過(guò)發(fā)送MQ,在消費(fèi)者線(xiàn)程去同步Redis

無(wú)論是更新緩存還是刪除緩存,在同時(shí)操作緩存和數(shù)據(jù)庫(kù)時(shí),都無(wú)法保證兩者都能一次性操作成功,所以我們最好的辦法就是重試,這個(gè)重試并不是立即重試,因?yàn)榫彺婧蛿?shù)據(jù)庫(kù)可能因?yàn)榫W(wǎng)絡(luò)或者其它原因停止服務(wù)了,立即重試成功率極低,而且重試會(huì)占用線(xiàn)程資源,顯然不合理,所以我們需要采用異步重試機(jī)制。

異步重試我們可以使用消息隊(duì)列來(lái)完成,因?yàn)橄㈥?duì)列可以保證消息的可靠性,消息不會(huì)丟失,也可以保證正確消費(fèi),當(dāng)且僅當(dāng)消息消費(fèi)成功后才會(huì)將消息從消息隊(duì)列中刪除。

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

優(yōu)點(diǎn)2:MQ本身有重試機(jī)制,無(wú)需人工去寫(xiě)重試代碼

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

4.3.3、Canal 訂閱日志實(shí)現(xiàn)

當(dāng)我們業(yè)務(wù)修改數(shù)據(jù)時(shí),我們只需要更新數(shù)據(jù)庫(kù),無(wú)需修改緩存,那什么時(shí)候修改緩存呢?

以mysql為例,在數(shù)據(jù)庫(kù)一條記錄發(fā)生變更時(shí)就會(huì)生成一條binlog日志,我們可以訂閱這種消息,拿到具體的數(shù)據(jù),然后根據(jù)日志消息更新緩存,訂閱日志目前比較流行的就是阿里開(kāi)源的canal,那么我們的架構(gòu)就變?yōu)槿缦滦问健?/p>

訂閱數(shù)據(jù)庫(kù)變更日志,當(dāng)數(shù)據(jù)庫(kù)發(fā)生變更時(shí),我們可以拿到具體操作的數(shù)據(jù),然后再去根據(jù)具體的數(shù)據(jù),去刪除對(duì)應(yīng)的緩存。

當(dāng)然Canal 也是要配合消息隊(duì)列一起來(lái)使用的,因?yàn)槠銫anal本身是沒(méi)有數(shù)據(jù)處理能力的。

這個(gè)方式算的上徹底解耦了,應(yīng)用程序代碼無(wú)需再管消息隊(duì)列方面發(fā)送失敗問(wèn)題,全交由 Canal來(lái)發(fā)送。

責(zé)任編輯:武曉燕 來(lái)源: 今日頭條
相關(guān)推薦

2016-11-29 09:00:19

分布式數(shù)據(jù)一致性CAS

2022-06-21 21:47:13

數(shù)據(jù)系統(tǒng)

2022-05-31 08:37:59

RedisMySQL數(shù)據(jù)一致性

2023-06-29 08:00:59

redis數(shù)據(jù)MySQL

2024-04-11 13:45:14

Redis數(shù)據(jù)庫(kù)緩存

2012-09-24 09:35:42

分布式系統(tǒng)

2019-05-27 09:00:00

蘇寧智慧零售平臺(tái)數(shù)據(jù)庫(kù)

2023-06-07 08:10:29

2022-09-06 15:30:20

緩存一致性

2023-04-13 08:15:47

Redis緩存一致性

2022-02-17 21:04:27

數(shù)據(jù)庫(kù)MysqlRedis

2023-05-26 07:34:50

RedisMySQL緩存

2021-12-14 07:15:57

MySQLRedis數(shù)據(jù)

2022-09-15 10:37:46

MySQLRedis數(shù)據(jù)一致性

2024-11-14 07:10:00

2018-10-25 14:40:23

分布式數(shù)據(jù)數(shù)據(jù)不一致

2025-03-27 08:20:54

2023-05-09 10:59:33

緩存技術(shù)派MySQL

2022-08-11 07:55:05

數(shù)據(jù)庫(kù)Mysql

2024-11-07 22:57:30

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)