91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

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

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

Redis跟MySQL的雙寫問題怎么解決

發布時間:2022-02-24 16:43:45 來源:億速云 閱讀:131 作者:iii 欄目:開發技術

本文小編為大家詳細介紹“RedisMySQL的雙寫問題怎么解決”,內容詳細,步驟清晰,細節處理妥當,希望這篇“Redis跟MySQL的雙寫問題怎么解決”文章能幫助大家解決疑惑,下面跟著小編的思路慢慢深入,一起來學習新知識吧。

寫在前面

嚴格意義上任何非原子操作都不可能保證一致性,除非用阻塞讀寫實現強一致性,所以緩存架構我們追求的目標是最終一致性。
緩存就是通過犧牲強一致性來提高性能的。

這是由CAP理論決定的。緩存系統適用的場景就是非強一致性的場景,它屬于CAP中的AP。

以下3 種緩存讀寫策略各有優劣,不存在最佳。

三種讀寫緩存策略

Cache-Aside Pattern(旁路緩存模式)

Cache-Aside Pattern,即旁路緩存模式,它的提出是為了盡可能地解決緩存與數據庫的數據不一致問題。

:從緩存讀取數據,讀到直接返回。如果讀取不到的話,從數據庫加載,寫入緩存后,再返回響應。
:更新的時候,先更新數據庫,然后再刪除緩存

Read-Through/Write-Through(讀寫穿透)

Read/Write Through Pattern 中服務端把 cache 視為主要數據存儲,從中讀取數據并將數據寫入其中。cache 服務負責將此數據讀取和寫入 DB,從而減輕了應用程序的職責。

因為我們經常使用的分布式緩存 Redis 并沒有提供 cache 將數據寫入DB的功能,所以使用并不多。

:先查 cache,cache 中不存在,直接更新 DB。cache 中存在,則先更新 cache,然后 cache 服務自己更新 DB(同步更新 cache和DB)。

:從 cache 中讀取數據,讀取到就直接返回 。讀取不到的話,先從 DB 加載,寫入到 cache 后返回響應。

Write Behind Pattern(異步緩存寫入)

Write Behind Pattern 和 Read/Write Through Pattern 很相似,兩者都是由 cache 服務來負責 cache 和 DB 的讀寫。

但是,兩個又有很大的不同:Read/Write Through 是同步更新 cache 和 DB,而 Write Behind Caching 則是只更新緩存,不直接更新 DB,而是改為異步批量的方式來更新 DB。

很明顯,這種方式對數據一致性帶來了更大的挑戰,比如cache數據可能還沒異步更新DB的話,cache服務可能就掛掉了,反而會帶來更大的災難。

這種策略在我們平時開發過程中也非常非常少見,但是不代表它的應用場景少,比如消息隊列中消息的異步寫入磁盤、MySQL 的 InnoDB Buffer Pool 機制都用到了這種策略。

Write Behind Pattern 下 DB 的寫性能非常高,非常適合一些數據經常變化又對數據一致性要求沒那么高的場景,比如瀏覽量、點贊量。

旁路緩存模式解析

Cache Aside Pattern 的一些疑問

旁路緩存模式是我們平時中使用最多的。下面根據上面介紹的旁路緩存模式,我們可以有以下幾個疑問。

為什么寫操作是刪除緩存,而不是更新緩存

:線程A先發起一個寫操作,第一步先更新數據庫。線程B再發起一個寫操作,第二步更新了數據庫,由于網絡等原因,線程B先更新了緩存,線程A更新緩存。

這時候,緩存保存的是A的數據(老數據),數據庫保存的是B的數據(新數據),數據不一致了,臟數據出現啦。如果是刪除緩存取代更新緩存則不會出現這個臟數據問題。

實際上要寫操作的時候更新緩存也是可以的,不過我們需要加一個鎖/分布式鎖來保證更新cache的時候不存在線程安全問題。

在寫數據的過程中,為什么要先更新DB在刪除緩存

:比如說請求1 是寫操作,要是先刪除緩存A,請求2是讀操作,先讀緩存A,發現緩存被刪除了(被請求1刪除了),然后去讀數據庫,但是此時請求1還沒來得及把數據及時更新,那么請求2讀的就是舊數據,并且請求2還會把讀到的舊數據放到緩存中,造成了數據的不一致。

其實要先刪緩存,再更新數據庫也是可以,如采用延時雙刪策略
休眠1秒,再次淘汰緩存 這么做,可以將1秒內所造成的緩存臟數據,再次刪除。不一定是1秒,看你業務決定的,不過不推薦這種做法,因為在這1秒內可能發生因素很多,它的不確定性太大。

在寫數據的過程中,先更新DB,后刪除cache就沒有問題了么?

答: 理論上來說還是可能會出現數據不一致性的問題,不過概率非常小。

假設這會有兩個請求,一個請求A做查詢操作,一個請求B做更新操作,那么會有如下情形產生

(1)緩存剛好失效
(2)請求A查詢數據庫,得一個舊值
(3)請求B將新值寫入數據庫
(4)請求B刪除緩存
(5)請求A將查到的舊值寫入緩存 ok,如果發生上述情況,確實是會發生臟數據。

然而,發生這種情況的概率并不高

發生上述情況有一個先天性條件,就是步驟(3)的寫數據庫操作比步驟(2)的讀數據庫操作耗時更短,才有可能使得步驟(4)先于步驟(5)。

可是,仔細想想,數據庫的讀操作的速度遠快于寫操作的(不然做讀寫分離干嘛,做讀寫分離的意義就是因為讀操作比較快,耗資源少),因此步驟(3)耗時比步驟(2)更短,這一情形很難出現。

還有其他造成不一致的原因么?

答: 如果刪除緩存過程中失敗了就會造成不一致問題

如何解決?
使用Canal去訂閱數據庫的binlog,獲得需要操作的數據。另起一個程序,獲得這個訂閱程序傳來的信息,進行刪除緩存操作。

Cache Aside Pattern 的缺陷

缺陷1:首次請求數據一定不在 cache 的問題

解決辦法:可以將熱點數據提前放入cache 中。

缺陷2:寫操作比較頻繁的話導致cache中的數據會被頻繁被刪除,這樣會影響緩存命中率 。

數據庫和緩存數據強一致場景 :更新DB的時候同樣更新cache,不過我們需要加一個鎖/分布式鎖來保證更新cache的時候不存在線程安全問題。可以短暫地允許數據庫和緩存數據不一致的場景 :更新DB的時候同樣更新cache,但是給緩存加一個比較短的過期時間,這樣的話就可以保證即使數據不一致的話影響也比較小。

讀到這里,這篇“Redis跟MySQL的雙寫問題怎么解決”文章已經介紹完畢,想要掌握這篇文章的知識點還需要大家自己動手實踐使用過才能領會,如果想了解更多相關內容的文章,歡迎關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

潜江市| 武邑县| 诸城市| 冀州市| 乌拉特后旗| 秀山| 子长县| 汽车| 康马县| 六安市| 观塘区| 诏安县| 神木县| 临漳县| 来安县| 八宿县| 兴城市| 汶上县| 张家界市| 洛南县| 庆阳市| 大港区| 饶阳县| 嘉义市| 赫章县| 江永县| 遂平县| 紫金县| 朔州市| 泾川县| 兴国县| 吉木萨尔县| 白朗县| 卢湾区| 揭阳市| 本溪| 盐城市| 渭南市| 肥东县| 三门峡市| 泽库县|