快取與資料庫不一致,咋辦?
快取與資料庫的操作時序,不管是《Cache Aside Pattern》中的方案,還是《究竟先操作快取,還是資料庫?》中的方案,都會遇到快取與資料庫不一致的問題。今天聊聊這個問題。
一、資料庫主從不一致
先回顧下,無快取時,資料庫主從不一致問題。
如上圖,發生的場景是,寫後立刻讀:
(1)主庫一個寫請求(主從沒同步完成)
(2)從庫接著一個讀請求,讀到了舊資料
(3)最後,主從同步完成
導致的結果是:主動同步完成之前,會讀取到舊資料。
可以看到,主從不一致的影響時間很短,在主從同步完成後,就會讀到新資料。
二、快取與資料庫不一致
再看,引入快取後,快取和資料庫不一致問題。
如上圖,發生的場景也是,寫後立刻讀:
(1+2)先一個寫請求,淘汰快取,寫資料庫
(3+4+5)接著立刻一個讀請求,讀快取,cache miss,讀從庫,寫快取放入資料,以便後續的讀能夠cache hit(主從同步沒有完成,快取中放入了舊資料)
(6)最後,主從同步完成
導致的結果是:舊資料放入快取,即使主從同步完成,後續仍然會從快取一直讀取到舊資料。
可以看到,加入快取後,導致的不一致影響時間會很長,並且最終也不會達到一致。
三、問題分析
可以看到,這裡提到的快取與資料庫資料不一致,根本上是由資料庫主從不一致引起的。當主庫上發生寫操作之後,從庫binlog同步的時間間隔內,讀請求,可能導致有舊資料入快取。
假如主從不一致沒法徹底解決,引入快取之後,binlog同步時間間隔內,也無法避免讀舊資料。
但是,有沒有辦法做到,即使引入快取,不一致不會比“不引入快取”更糟呢?這是更為實際的優化目標。
思路轉化為:在從庫同步完成之後,如果有舊資料入快取,應該及時把這個舊資料淘汰掉。
四、不一致優化
如上圖所述,在併發讀寫導致快取中讀入了髒資料之後:
(6)主從同步
(7)通過工具訂閱從庫的binlog,這裡能夠最準確的知道,從庫資料同步完成的時間
畫外音:本圖畫的訂閱工具是DTS,可以是cannal,也可以自己訂閱和分析binlog
(8)從庫執行完寫操作,向快取再次發起刪除,淘汰這段時間內可能寫入快取的舊資料
如此這般,至少能夠保證,引入快取之後,主從不一致,不會比沒有引入快取更壞。
畫外音:即使引入快取,也只有一個很小的時間間隔,可能讀到舊資料。
五、結尾
問:如何完全避免,主從同步時間差,資料的一致性?
答:詳見《資料庫主從不一致,怎麼解?》。
問:該方案,只能優化,併發讀寫情況下,快取與資料庫一致性問題。如果,快取與資料庫兩次操作,原子性被破壞(例如:修改資料庫成功,淘汰快取失敗,導致的資料不一致),如何優化資料的一致性呢?
答:詳見《究竟先操作快取,還是資料庫?》。
【本文轉載自架構師之路微信公眾號,作者:58沈劍,原文連結:https://mp.weixin.qq.com/s/gYQvP69sao8U0azuNRMG1w】
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31077337/viewspace-2157921/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 快取與資料庫雙寫,不一致問題及解決方案快取資料庫
- 深入分析與解決方案:快取與資料庫雙寫不一致問題快取資料庫
- 分散式快取--快取與資料庫一致性方案分散式快取資料庫
- 快取與資料庫一致性快取資料庫
- 快取與資料庫的一致性快取資料庫
- Redis快取穿透、擊穿、雪崩,資料庫與快取一致性Redis快取穿透資料庫
- 資料庫同步 Elasticsearch 後資料不一致,怎麼辦?資料庫Elasticsearch
- Python操作Redis快取資料庫PythonRedis快取資料庫
- 分散式快取--快取與資料庫強一致場景下的方案分散式快取資料庫
- RecyclerView快取機制(咋複用?)View快取
- 資料庫與快取資料一致性解決方案資料庫快取
- 資料庫與快取雙寫一致性資料庫快取
- 快取淘汰、快取穿透、快取擊穿、快取雪崩、資料庫快取雙寫一致性快取穿透資料庫
- Redis快取資料庫-快速入門Redis快取資料庫
- 快取與資料庫的雙寫一致性快取資料庫
- 使用Redis和Java進行資料庫快取 - DZone資料庫RedisJava資料庫快取
- 快取與資料庫一致性問題深度剖析快取資料庫
- 快取與資料庫雙寫一致性 深度分析快取資料庫
- 究竟先操作快取,還是資料庫?快取資料庫
- 資料庫分庫,原來 SQL 和儲存過程寫的報表咋辦?資料庫SQL儲存過程
- 用於Electron/Nodejs的資料持久快取庫NodeJS快取
- SpringBoot整合Canal進行資料庫 快取同步Spring Boot資料庫快取
- 使用Redis和Java進行資料庫快取RedisJava資料庫快取
- 快取與資料庫雙寫一致性幾種策略分析快取資料庫
- 如何解決資料庫與快取的一致性問題資料庫快取
- 如何保證快取與資料庫的雙寫一致性?快取資料庫
- MySQL 資料庫的提速器-寫快取(Change Buffer)MySql資料庫快取
- 使用 Infinispan 快取功能支援多個 Redis 資料庫快取Redis資料庫
- PbootCMS快取如何清理runtime資料夾下經常滿怎麼辦?清理快取的方法boot快取
- 如何保證快取(redis)與資料庫的雙寫一致性快取Redis資料庫
- ServiceWorker 快取與 HTTP 快取快取HTTP
- 快取架構設計細節二三事--究竟先操作快取,還是資料庫?快取架構資料庫
- config 裡面的database 資料庫 連線取不到 .env 裡面的資料庫配置,所有快取已清,求解Database資料庫快取
- 巧妙設計多級快取,為資料庫減負快取資料庫
- Laravel Passport OAuth 資料庫查詢改快取優化LaravelPassportOAuth資料庫快取優化
- 直播賣貨系統,使用資料庫查詢快取資料庫快取
- 關於redis快取資料庫的一些思考Redis快取資料庫
- Caffeine 快取庫快取