搜尋
首頁資料庫Redis如何保證Redis快取與資料庫的一致性

這篇文章為大家帶來了關於Redis的相關知識,其中主要介紹如何保證redis快取與資料庫的一致性相關問題,其中包括了更新快取和更新資料庫等等,希望對大家有幫助。

如何保證Redis快取與資料庫的一致性

推薦學習:Redis學習教學

#1、四個同步策略:

想要確保緩存與資料庫的雙寫一致,一共有4種方式,即4種同步策略:

  1. 先更新緩存,再更新資料庫;
  2. 先更新資料庫,再更新快取;
  3. 先刪除快取,再更新資料庫;
  4. 先更新資料庫,再刪除快取。

從這4種同步策略中,我們需要做出比較的是:

更新快取與刪除快取哪種方式比較適合?應該先操作資料庫還是先操作快取?

2、更新快取還是刪除快取

下面,我們來分析一下,應該採用更新快取還是刪除快取的方式。

2.1 更新快取

優點每次資料變更都會及時更新緩存,所以查詢時不容易出現未命中的情況。

缺點更新快取的消耗比較大。如果資料需要經過複雜的計算再寫入緩存,那麼頻繁的更新緩存,就會影響伺服器的效能。如果是寫入資料頻繁的業務場景,那麼可能頻繁的更新快取時,卻沒有業務讀取該資料。

2.2 刪除快取

優點操作簡單,無論更新操作是否複雜,都是直接刪除快取中的資料。

缺點刪除快取後,下次查詢快取會出現未命中,這時需要重新讀取一次資料庫。從上面的比較來看,一般情況下,刪除快取是更優的方案。

3、先操作資料庫還是快取

下面,我們再來分析一下,應該先操作資料庫還是先操作快取。
首先,我們將先刪除快取與先更新資料庫,在出現失敗時做一個比較:

3.1 先刪除快取再更新資料庫

如何保證Redis快取與資料庫的一致性
如上圖,是先刪除快取再更新資料庫,出現失敗時可能出現的問題:

  • 執行緒A刪除快取成功,執行緒A更新資料庫失敗;
  • 線程B從快取中讀取資料;由於快取被刪,進程B無法從快取中得到數據,進而從資料庫讀取資料;此時資料庫中的資料更新失敗,線程B從資料庫成功取得舊的數據,然後將資料更新到了快取。
  • 最終,快取和資料庫的資料是一致的,但仍然是舊的資料

3.2 先更新資料庫再刪除快取

如何保證Redis快取與資料庫的一致性
如上圖,是先更新資料庫再刪除緩存,在出現失敗時可能出現的問題:

  • 執行緒A更新資料庫成功,執行緒A刪除快取失敗;
  • 執行緒B讀取快取成功,由於快取刪除失敗,所以執行緒B讀取到的是快取中舊的資料。
  • 最後線程A刪除快取成功,有別的線程訪問緩存同樣的數據,與資料庫中的數據是一樣。
  • 最終,快取和資料庫的資料是一致的,但是會有一些執行緒讀到舊的資料。

經過上面的比較,我們發現在出現失敗的時候,是無法明確分辨出先刪快取和先更新資料庫哪個方式更好,以為它們都存在問題。後面我們會進一步對這兩種方式進行比較,但是在這裡我們先探討一下,上述場景出現的問題,該如何解決呢?

實際上,無論上面我們採用哪種方式去同步快取與資料庫,在第二步出現失敗的時候,都建議採用重試機制解決,上面兩張圖中已經畫了。




下面我們再將先刪快取與先更新資料庫,在沒有出現失敗時進行比較:
如何保證Redis快取與資料庫的一致性
#如上圖,是先刪除快取再更新資料庫,在沒有出現失敗時可能出現的問題:

  • 線程A刪除快取成功;
  • 線程B讀取快取失敗;
  • 線程B讀取資料庫成功,得到舊的資料;
  • 線程B將舊的資料成功地更新到了快取;
  • 線程A將新的資料成功地更新到資料庫。

可見,進程A的兩步驟操作都成功,但由於存在並發,在這兩個步驟之間,進程B存取了快取。 最終結果是,快取中儲存了舊的數據,而資料庫中儲存了新的數據,二者數據不一致。



如何保證Redis快取與資料庫的一致性
如上圖,是先更新資料庫再刪除緩存,在沒有出現失敗時可能出現的問題:

  • 線程A更新資料庫成功;
  • 線程B讀取快取成功;
  • 線程A刪除快取成功。

可見,最終快取與資料庫的資料是一致的,而且都是最新的資料。但線程B在這個過程裡讀到了舊的數據,可能還有其他線程也像線程B一樣,在這兩步之間讀到了緩存中舊的數據,但因為這兩步的執行速度會比較快,所以影響不大。對於這兩步驟之後,其他行程再讀取快取資料的時候,就不會出現類似進程B的問題了。

最終結論:

經過比較你會發現,先更新資料庫、再刪除快取是影響更小的方案。如果第二步出現失敗的情況,則可以採用重試機制解決問題。

4、延時雙刪

上面我們提到,如果是先刪快取、再更新資料庫,在沒有出現失敗時可能會導致數據的不一致。如果在實際的應用中,出於某些考慮我們需要選擇這種方式,那麼有辦法解決這個問題嗎?答案是有的,就是採用延時雙刪的策略,延時雙刪的基本想法如下

    ##刪除快取;
  1. 更新資料庫;
  2. sleep N毫秒;
  3. 再次刪除快取。
  4. 	public void write(String key, Object data) {
            Redis.delKey(key);
            db.updateData(data);
            Thread.sleep(1000);
            Redis.delKey(key);
        }

阻塞一段時間之後,再刪除緩存,就可以把這個過程中快取中不一致的資料刪除掉。而具體的時間,要評估你這項業務的大致時間,按照這個時間來設定即可。

4.1 採用讀寫分離的架構怎麼辦?

如果資料庫採用的是讀寫分離的架構,那麼又會出現新的問題,如下圖:


如何保證Redis快取與資料庫的一致性 此時來了兩個請求,請求A(更新操作) 和請求B(查詢操作)

    請求A 更新操作,刪除了Redis;
  1. 請求主庫進⾏更新操作,主庫與從庫進行同步資料的操作;
  2. 請B 查詢操作,發現Redis 中沒有數據;
  3. 去從庫中拿去數據;
  4. 此時同步數據還未完成,拿到的數據是舊資料;
此時的解決方法就是如果是對Redis 進行填充資料的查詢資料庫操作,那麼就強制將其指向主庫進⾏查詢。

刪除失敗了怎麼辦?

如果刪除依然失敗,則可以增加重試的次數,但是這個次數要有限制,當超出一定的次數時,要採取報錯、記日誌、發郵件提醒等措施。

5、利用訊息佇列進行刪除的補償

先更新資料庫,後刪除快取這⼀種情況也會出現問題,例如更新資料庫成功了,但是在刪除快取的階段出錯了沒有刪除成功,那麼此時再讀取快取的時候每次都是錯誤的資料了。
如何保證Redis快取與資料庫的一致性

此時解決方案就是利用訊息佇列進行刪除的補償。具體的業務邏輯⽤語⾔描述如下:

    請求線程A 先對資料庫進行更新操作;
  1. 在對Redis 進行刪除操作的時候發現報錯,刪除失敗;
  2. 此時將Redis 的key 作為訊息體傳送到訊息佇列中;
  3. 系統接收到訊息佇列發送的訊息後再次對Redis 進行刪除動作;
但這個方案會有⼀個缺點就是會對業務代碼造成大量的侵入,深深的耦合在⼀起,所以這時會有⼀個優化的方法,我們知道對Mysql 資料庫更新操作後再binlog 日誌中我們都能夠找到對應的操作,那麼我們可以訂閱Mysql 資料庫的binlog 日誌對快取進行操作。


如何保證Redis快取與資料庫的一致性

推薦學習:

Redis教學

以上是如何保證Redis快取與資料庫的一致性的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文轉載於:CSDN。如有侵權,請聯絡admin@php.cn刪除
es和redis区别es和redis区别Jul 06, 2019 pm 01:45 PM

Redis是现在最热门的key-value数据库,Redis的最大特点是key-value存储所带来的简单和高性能;相较于MongoDB和Redis,晚一年发布的ES可能知名度要低一些,ES的特点是搜索,ES是围绕搜索设计的。

一起来聊聊Redis有什么优势和特点一起来聊聊Redis有什么优势和特点May 16, 2022 pm 06:04 PM

本篇文章给大家带来了关于redis的相关知识,其中主要介绍了关于redis的一些优势和特点,Redis 是一个开源的使用ANSI C语言编写、遵守 BSD 协议、支持网络、可基于内存、分布式存储数据库,下面一起来看一下,希望对大家有帮助。

实例详解Redis Cluster集群收缩主从节点实例详解Redis Cluster集群收缩主从节点Apr 21, 2022 pm 06:23 PM

本篇文章给大家带来了关于redis的相关知识,其中主要介绍了Redis Cluster集群收缩主从节点的相关问题,包括了Cluster集群收缩概念、将6390主节点从集群中收缩、验证数据迁移过程是否导致数据异常等,希望对大家有帮助。

Redis实现排行榜及相同积分按时间排序功能的实现Redis实现排行榜及相同积分按时间排序功能的实现Aug 22, 2022 pm 05:51 PM

本篇文章给大家带来了关于redis的相关知识,其中主要介绍了Redis实现排行榜及相同积分按时间排序,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,希望对大家有帮助。

详细解析Redis中命令的原子性详细解析Redis中命令的原子性Jun 01, 2022 am 11:58 AM

本篇文章给大家带来了关于redis的相关知识,其中主要介绍了关于原子操作中命令原子性的相关问题,包括了处理并发的方案、编程模型、多IO线程以及单命令的相关内容,下面一起看一下,希望对大家有帮助。

一文搞懂redis的bitmap一文搞懂redis的bitmapApr 27, 2022 pm 07:48 PM

本篇文章给大家带来了关于redis的相关知识,其中主要介绍了bitmap问题,Redis 为我们提供了位图这一数据结构,位图数据结构其实并不是一个全新的玩意,我们可以简单的认为就是个数组,只是里面的内容只能为0或1而已,希望对大家有帮助。

实例详解Redis实现排行榜及相同积分按时间排序功能的实现实例详解Redis实现排行榜及相同积分按时间排序功能的实现Aug 26, 2022 pm 02:09 PM

本篇文章给大家带来了关于redis的相关知识,其中主要介绍了Redis实现排行榜及相同积分按时间排序,本文通过实例代码给大家介绍的非常详细,下面一起来看一下,希望对大家有帮助。

redis error什么意思redis error什么意思Jun 17, 2019 am 11:07 AM

redis error就是redis数据库和其组合使用的部件出现错误,这个出现的错误有很多种,例如Redis被配置为保存数据库快照,但它不能持久化到硬盘,用来修改集合数据的命令不能用。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
3 週前By尊渡假赌尊渡假赌尊渡假赌

熱工具

Dreamweaver Mac版

Dreamweaver Mac版

視覺化網頁開發工具

DVWA

DVWA

Damn Vulnerable Web App (DVWA) 是一個PHP/MySQL的Web應用程序,非常容易受到攻擊。它的主要目標是成為安全專業人員在合法環境中測試自己的技能和工具的輔助工具,幫助Web開發人員更好地理解保護網路應用程式的過程,並幫助教師/學生在課堂環境中教授/學習Web應用程式安全性。 DVWA的目標是透過簡單直接的介面練習一些最常見的Web漏洞,難度各不相同。請注意,該軟體中

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

EditPlus 中文破解版

EditPlus 中文破解版

體積小,語法高亮,不支援程式碼提示功能

SublimeText3 Linux新版

SublimeText3 Linux新版

SublimeText3 Linux最新版