搜尋
首頁資料庫mysql教程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的雙寫問題怎麼解決的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文轉載於:亿速云。如有侵權,請聯絡admin@php.cn刪除
MySQL的許可與其他數據庫系統相比如何?MySQL的許可與其他數據庫系統相比如何?Apr 25, 2025 am 12:26 AM

MySQL使用的是GPL許可證。 1)GPL許可證允許自由使用、修改和分發MySQL,但修改後的分發需遵循GPL。 2)商業許可證可避免公開修改,適合需要保密的商業應用。

您什麼時候選擇InnoDB而不是Myisam,反之亦然?您什麼時候選擇InnoDB而不是Myisam,反之亦然?Apr 25, 2025 am 12:22 AM

選擇InnoDB而不是MyISAM的情況包括:1)需要事務支持,2)高並發環境,3)需要高數據一致性;反之,選擇MyISAM的情況包括:1)主要是讀操作,2)不需要事務支持。 InnoDB適合需要高數據一致性和事務處理的應用,如電商平台,而MyISAM適合讀密集型且無需事務的應用,如博客系統。

在MySQL中解釋外鍵的目的。在MySQL中解釋外鍵的目的。Apr 25, 2025 am 12:17 AM

在MySQL中,外鍵的作用是建立表與表之間的關係,確保數據的一致性和完整性。外鍵通過引用完整性檢查和級聯操作維護數據的有效性,使用時需注意性能優化和避免常見錯誤。

MySQL中有哪些不同類型的索引?MySQL中有哪些不同類型的索引?Apr 25, 2025 am 12:12 AM

MySQL中有四種主要的索引類型:B-Tree索引、哈希索引、全文索引和空間索引。 1.B-Tree索引適用於範圍查詢、排序和分組,適合在employees表的name列上創建。 2.哈希索引適用於等值查詢,適合在MEMORY存儲引擎的hash_table表的id列上創建。 3.全文索引用於文本搜索,適合在articles表的content列上創建。 4.空間索引用於地理空間查詢,適合在locations表的geom列上創建。

您如何在MySQL中創建索引?您如何在MySQL中創建索引?Apr 25, 2025 am 12:06 AM

toCreateAnIndexinMysql,usethecReateIndexStatement.1)forasingLecolumn,使用“ createIndexIdx_lastNameEnemployees(lastName); 2)foracompositeIndex,使用“ createIndexIndexIndexIndexIndexDx_nameOmplayees(lastName,firstName,firstName);” 3)forauniqe instex,creationexexexexex,

MySQL與Sqlite有何不同?MySQL與Sqlite有何不同?Apr 24, 2025 am 12:12 AM

MySQL和SQLite的主要區別在於設計理念和使用場景:1.MySQL適用於大型應用和企業級解決方案,支持高性能和高並發;2.SQLite適合移動應用和桌面軟件,輕量級且易於嵌入。

MySQL中的索引是什麼?它們如何提高性能?MySQL中的索引是什麼?它們如何提高性能?Apr 24, 2025 am 12:09 AM

MySQL中的索引是數據庫表中一列或多列的有序結構,用於加速數據檢索。 1)索引通過減少掃描數據量提升查詢速度。 2)B-Tree索引利用平衡樹結構,適合範圍查詢和排序。 3)創建索引使用CREATEINDEX語句,如CREATEINDEXidx_customer_idONorders(customer_id)。 4)複合索引可優化多列查詢,如CREATEINDEXidx_customer_orderONorders(customer_id,order_date)。 5)使用EXPLAIN分析查詢計劃,避

說明如何使用MySQL中的交易來確保數據一致性。說明如何使用MySQL中的交易來確保數據一致性。Apr 24, 2025 am 12:09 AM

在MySQL中使用事務可以確保數據一致性。 1)通過STARTTRANSACTION開始事務,執行SQL操作後用COMMIT提交或ROLLBACK回滾。 2)使用SAVEPOINT可以設置保存點,允許部分回滾。 3)性能優化建議包括縮短事務時間、避免大規模查詢和合理使用隔離級別。

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脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

SecLists

SecLists

SecLists是最終安全測試人員的伙伴。它是一個包含各種類型清單的集合,這些清單在安全評估過程中經常使用,而且都在一個地方。 SecLists透過方便地提供安全測試人員可能需要的所有列表,幫助提高安全測試的效率和生產力。清單類型包括使用者名稱、密碼、URL、模糊測試有效載荷、敏感資料模式、Web shell等等。測試人員只需將此儲存庫拉到新的測試機上,他就可以存取所需的每種類型的清單。

mPDF

mPDF

mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),

SublimeText3 Linux新版

SublimeText3 Linux新版

SublimeText3 Linux最新版

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

DVWA

DVWA

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