最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

如何保證redis和MySQL數(shù)據(jù)的一致性

2023-03-04 10:32 作者:取悅疾風(fēng)  | 我要投稿

來自尚硅谷redis7 p109

首先說結(jié)論:無法保證100%的數(shù)據(jù)強(qiáng)一致性,只要是雙寫,悲觀角度看待一定會出現(xiàn)數(shù)據(jù)不一致問題,這個就好比一個人又要向左看又要向右看一樣,是不可能的,除非你有影分身

介紹4種思路

1 先更新數(shù)據(jù)庫,再更新緩存

適用場景:服務(wù)器停機(jī)狀態(tài)下可以使用這種方法

在不停機(jī)的情況下

可能出現(xiàn)的問題:1?MySQL更新成功 redis失敗

舉例:先更新了MySQL,假設(shè)數(shù)量從100改為99,然后回寫進(jìn)redis的時候發(fā)生了異常,導(dǎo)致MySQL內(nèi)是99,redis內(nèi)還是100,下次讀取操作會命中redis,將100返回導(dǎo)致數(shù)據(jù)不一致

可能出現(xiàn)的問題:2 多線程環(huán)境下,每個線程的執(zhí)行消耗時間不一致,導(dǎo)致出現(xiàn)問題

舉例:線程A在更新數(shù)據(jù)庫的時候B線程也要更新同一個數(shù)據(jù)此時發(fā)生了如下情況

現(xiàn)在要把數(shù)據(jù)從100改為99

A線程帶著99正在走路去更新的路上...

需求緊急變更,要改為98

B線程火速坐飛機(jī)帶著98殺進(jìn)來更新

B線程更新完了,回寫進(jìn)redis,任務(wù)完成

A線程終于走到站了,把更新的數(shù)據(jù)寫入MySQL

A線程回寫進(jìn)redis,任務(wù)完成

B表示???更新了個寂寞,白干了

不推薦

2 先更新緩存,再更新數(shù)據(jù)庫

不推薦 因為一般會把數(shù)據(jù)庫最為最終解釋數(shù)據(jù),不會把緩存數(shù)據(jù)當(dāng)作最終數(shù)據(jù)

正常邏輯:

A更新redis

A更新MySQL

B更新redis

B更新MySQL

多線程情況下可能會出現(xiàn)這個問題

數(shù)據(jù)庫內(nèi)數(shù)據(jù)為100

A更新redis? ==>99

B更新redis ===>98

B更新數(shù)據(jù)庫 ===>98

A更新數(shù)據(jù)庫 ===>99

一頓操作完成后

redis => 98

MySQL => 99

導(dǎo)致不一致

不推薦

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

可能出現(xiàn)的問題 1 A線程刪除redis,正在更新MySQL,B來讀取MySQL

此時A正在更新,B讀取到了舊的數(shù)據(jù),然后將舊數(shù)據(jù)寫入redis,導(dǎo)致A線程在MySQL中更新完后發(fā)現(xiàn)redis里面有臟數(shù)據(jù),就無動于衷,不管了

解決方案:延時雙刪

實現(xiàn)方式:

先刪除redis里面的值,然后正常執(zhí)行業(yè)務(wù)邏輯,執(zhí)行完成后再去刪除redis里面的緩存

此時,按照上面問題1 的邏輯,A先刪除redis,去更新MySQL,此時B來查找,redis無,找MySQL,找到,返回并寫入redis,B雖然返回的是舊數(shù)據(jù),但是B完事了,此時A對MySQL的操作完成了,再去刪除redis里面的緩存,就把B才寫入的舊數(shù)據(jù)又干掉了,這樣,當(dāng)C線程再來查詢的時候,redis里面沒有,去MySQL里面查詢到的就是A更新完的最新的數(shù)據(jù),然后寫入redis,就達(dá)成了redis和MySQL數(shù)據(jù)一致

但是上述實現(xiàn)方式又有一個問題

問題1

A處理業(yè)務(wù)邏輯的時間一定要大于B讀取數(shù)據(jù)并寫入redis的時間,那A要干活多久呢?

方法1?

在業(yè)務(wù)程序運行的時候,統(tǒng)部下線程讀數(shù)據(jù)和寫緩存的操作時間,自行評估自己的項目的讀數(shù)據(jù)業(yè)務(wù)邏輯的耗時,以此為基礎(chǔ)來進(jìn)行估算。然后寫數(shù)據(jù)的休眠時間則在讀數(shù)據(jù)業(yè)務(wù)邏輯的耗時基礎(chǔ)上加百毫秒即可。(我覺得不行,不要犯經(jīng)驗主義的錯誤)

方法2

新啟動一個后臺監(jiān)控程序,比如后面要講解的WatchDog監(jiān)控程序,會加時(我覺得可)

問題2

這種同步淘汰策略,吞吐量降低怎么辦?

說明:起一個異步線程刪除redis里面的數(shù)據(jù)

結(jié)論:能用,比較麻煩,建議看4

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

邏輯順序介紹:

A線程更新了MySQL,B突然來查詢,發(fā)現(xiàn)有,然后就返回了舊值,B的事情干完了,A更新MySQL完成后,去把redis緩存刪除,這樣,C線程再來讀取的時候,redis里沒有,就去MySQL內(nèi)讀取到了最新值,并寫入了redis

結(jié)論:這樣是比較穩(wěn)妥的方案,建議使用

但是還有最后一個問題:數(shù)據(jù)的最終一致性

解決方案:消息中間件

小總結(jié):


如何保證redis和MySQL數(shù)據(jù)的一致性的評論 (共 條)

分享到微博請遵守國家法律
林甸县| 洛浦县| 麻江县| 忻州市| 哈尔滨市| 岳普湖县| 册亨县| 富裕县| 客服| 色达县| 精河县| 九江县| 新乡市| 响水县| 新昌县| 英超| 张家港市| 丽水市| 原平市| 大渡口区| 乡城县| 奈曼旗| 南漳县| 金山区| 青海省| 西藏| 兰坪| 苏州市| 清水县| 兰州市| 九江县| 瑞昌市| 大冶市| 合作市| 大埔县| 花莲市| 定结县| 阿鲁科尔沁旗| 中阳县| 涞水县| 天峨县|