中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

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

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

如何更新緩存嗎?如何保證緩存和數據庫雙寫一致性?

發布時間:2020-07-17 17:41:07 來源:網絡 閱讀:7345 作者:若小寒 欄目:MySQL數據庫

目錄

  1. 前言
  2. 先更新數據庫,再更新緩存
  3. 先更新緩存,再更新數據庫
  4. 先刪除緩存,再更新數據庫
  5. 先更新數據庫,再刪除緩存
  6. 刪除緩存失敗,導致不一致
  7. 讀寫分離,導致不一致

前言

在項目中緩存是經常用到的,為了減少和數據庫的交互,小伙伴們利用緩存的思路如下:

如何更新緩存嗎?如何保證緩存和數據庫雙寫一致性?

緩存設計思路

我們小伙伴們有沒有考慮到緩存更新的問題,小伙伴們肯定會說肯定用過啊,有數據更新時,把緩存清空掉就行了啊,下一次訪問的時候服務就會把新值設置到緩存中了。這樣不就行了嗎?對的,在一般項目中,這樣的使用就夠了。那老顧帶著大家看看在高并發場景下,會有什么問題?

我們舉例說明,就拿商品的庫存作為緩存。那現在我們要更新緩存中的庫存值,怎么進行操作,我們看下面幾個場景:

先更新數據庫,再更新緩存

存在的問題場景:請求A更新值為99,請求B更新值為98

如何更新緩存嗎?如何保證緩存和數據庫雙寫一致性?

上圖流程:

  1. 請求A先發起,更新數據庫為99,但還沒有來得及更新緩存
  2. 請求B發起,更新數據庫為98,又更新了緩存值為98
  3. 請求A這時才更新緩存的值為99

這樣數據庫的值為98,但緩存的值為99,數值不一致。(不推薦)

先更新緩存,再更新數據庫

這個流程跟上面很類似,出現的問題也很類似

  1. 請求A先更新緩存為99,但還沒有來得及更新數據庫
  2. 請求B更新緩存為98,又更新了數據庫為98
  3. 請求A這時更新數據庫為99

這樣就緩存的值為98,數據庫為99導致不一致。(不推薦)

先刪除緩存,再更新數據庫

存在的問題場景:請求A更新值為99,請求B獲取值

如何更新緩存嗎?如何保證緩存和數據庫雙寫一致性?

上圖中請求流程:

  1. 請求A更新值,先把緩存中的值刪除,但還沒有來得及更新數據庫
  2. 此時請求B過來查詢此值,發現緩存中不存在,就到數據庫中查詢
  3. 請求B在數據庫中獲取到值,在把值設置到緩存中。
  4. 請求A這時才更新數據庫里面的值為99

這樣就導致了緩存和數據庫的不一致問題,緩存中的值一直是舊數據。(不推薦)

先更新數據庫,再刪除緩存

這個方案也是老外提出的《Cache-Aside pattern》更新緩存的策略。這種策略先保證了源頭的數據一定是正確的。這種策略是不是萬無一失呢,有一種非常特殊的場景

如何更新緩存嗎?如何保證緩存和數據庫雙寫一致性?

上圖流程:建立中緩存突然失效了

  1. 請求A發起查詢請求,直接到數據庫查詢到100,但還沒有來得及去設置緩存
  2. 請求B更新值,先更新數據庫,在刪除緩存
  3. 請求A這時才設置緩存為100

這種情況發生的不一致,是因為緩存突然失效了。而且還要保證請求B更新操作 比 請求A的查詢操作還要快;才會導致不一致。這種情況概率會很少。一般要求不高的項目可以采用此方式(推薦)。

緩存刪除失敗,導致不一致

這種先更新數據庫,再刪除緩存的策略中,因為要刪除緩存,但如果緩存刪除失敗,就會導致數據庫與緩存不一致。這個問題怎么辦?我們正常想到的是利用我們MQ中間件去實現。

如何更新緩存嗎?如何保證緩存和數據庫雙寫一致性?

上圖的流程,如果刪除緩存失敗,發送消息投遞到消息中間件中,進入消息隊列。也許有小伙伴就會問,如果消息投遞失敗怎么辦?我們可以利用消息中間件那邊的保證100%消息投遞的機制(這個以后再講)。這樣就保證了即使刪除消息失敗,我們也會重試。

不過這個方案有個問題,就是和我們應用服務的業務代碼耦合的比較厲害。代碼業務不清晰。

那我們有沒有別的方案呢,對業務沒有侵入呢?

如何更新緩存嗎?如何保證緩存和數據庫雙寫一致性?

上圖中其實是利用了mysql的底層機制,binlog日志進行刪除緩存,這樣就不需要和業務關聯,刪除緩存服務是獨立的。我們可以利用阿里開源的canal去操作。

讀寫分離,導致不一致

這種先更新數據庫,再刪除緩存的策略是不是就沒有問題呢?我們來看一下另一個場景,數據庫的讀寫分離的場景。一般中大型項目都會用到數據庫的讀寫分離。寫請求在一個庫,讀請求在另一個庫。讀寫分離會有個問題,就是庫與庫之間會存在數據延遲,因為存在數據同步。

那我們再看一下上面的場景流程,就會有問題,因為請求B更新數據 在一個庫上面,請求A去讀取數據時是另一個庫。

  1. 請求B更新值99,刪除緩存
  2. 請求A查詢值100(讀庫數據還沒有同步),在更新到緩存中(值為100)

這樣就導致不一致,這個場景是經常出現的,不是小概率事件。那我們如何處理呢?老顧下次再介紹。

總結:整個導致不一致的原因就是因為高并發情況下各個請求執行的順序是無法確定的,不知道哪個請求先執行,哪個后執行導致。

向AI問一下細節

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

AI

公安县| 隆德县| 牡丹江市| 新乐市| 临安市| 莆田市| 姚安县| 阜康市| 宜君县| 会理县| 阳东县| 徐州市| 深水埗区| 桂平市| 辽源市| 汕头市| 余姚市| 鱼台县| 大洼县| 汉阴县| 东丽区| 鄱阳县| 中方县| 横山县| 南投县| 红河县| 花莲县| 房山区| 博湖县| 志丹县| 筠连县| 桑植县| 黄浦区| 吉木乃县| 黄骅市| 库尔勒市| 纳雍县| 常山县| 吕梁市| 聂拉木县| 射洪县|