緩存與資料庫一緻性
- 前言
- 一、緩存是什麼?為什麼引入緩存?
-
- 1.緩存的引入
- 2.讀寫的性能提升
- 二、緩存一緻性
-
- 1.談談一緻性
- 2.三種經典的緩存模式
- 3.讨論三種資料更新方案
- 總結
前言
面試的時候被問到了不少關于緩存的問題,而緩存的一緻性問題是被問的最多的,當時沒怎麼答好,這次把關于緩存的問題都記錄下來,以做積累和沉澱。
參考文檔:https://mp.weixin.qq.com/s/urm2W1rBmIGa09w8K-hqvA
https://mp.weixin.qq.com/s/a4FRIKu1YWftnso2iBvWSw
一、緩存是什麼?為什麼引入緩存?
緩存的本質:彌補cpu的高算力和IO的慢讀寫之間巨大的鴻溝。
1.緩存的引入
- 在初期業務量小的時候,資料庫能承擔讀寫壓力,應用可以直接和DB互動,架構簡單且強壯。
- 當業務量大規模增加時,DB查詢壓力和耗時都在增長。此時引入分布式緩存,減少DB壓力的同時,還提供了高qps。
- 發展到後面,分布式緩存也成為瓶頸,高頻的qps成為負擔,另外緩存驅逐(緩存淘汰)和網絡抖動會影響系統的穩定性,此時引入本地緩存,可以減輕分布式緩存的壓力,并減少網絡和序列化開銷。
2.讀寫的性能提升
- 讀優化:當請求命中緩存後,可直接傳回,進而略過IO讀取,減小讀的成本。
- 寫優化:将寫操作在緩沖中合并,讓IO裝置可以批量處理,減小寫的成本。
二、緩存一緻性
1.談談一緻性
一緻性分為三種類型:
- 強一緻性:這種一緻性級别是最符合使用者直覺的。它要求系統寫入什麼,讀出來就是什麼,使用者體驗好,但是實作起來對系統的性能影響大。【CAP理論】
- 弱一緻性:這種級别限制了系統在寫入成功後,不保證立即可以讀到寫入的值,也不保證多久之後資料能夠達到一緻,但會盡可能保證某個時間級别後,資料能夠達到一緻狀态。
- 最終一緻性:最終一緻性是弱一緻性的一個特例,系統會保證在一定時間内,能夠達到資料一緻的狀态。業界大型系統較推崇的一種方式。
2.三種經典的緩存模式
有三種經典的緩存模式:
- cache-aside
- read/write through
- write behind
cache-aside
- 讀請求流程:
- 寫請求流程:
資料更新的時候,是先更新資料庫,再删除緩存。
這樣操作的原因在後面會解釋。
- 缺點:更新頻繁的場景會導緻緩存頻繁的被删除,降低了緩存的作用
- 适用場景:用于讀較多的場景
read/write through
read/write through的流程和cache aside流程一緻,隻不過中間多了一個緩存元件。
1.讀請求流程:
先查詢緩存中資料是否存在,如果存在則直接傳回,如果不存在,則由緩存元件負責從資料庫中同步加載資料。
2.寫請求流程:
由緩存元件完成資料源和緩存資料的更新。
write behind
write behind與read/write through有很多相似的地方,都是緩存元件來負責緩存和資料庫的讀寫。不同在于,read/write through是同步更新緩存和資料庫的,write behind則是隻更新緩存,不直接更新資料庫,通過批量異步的方式來更新資料庫。
1.write behind流程:
2.缺點:緩存與資料庫的一緻性不強。
3.讨論三種資料更新方案
在資料更新的時候,有幾種選擇,選擇是先更新資料庫還是先更新緩存,然後就是是删除緩存還是更新緩存,下面分别就這三種情況進行讨論。
先更新資料庫,再更新緩存
1.問題
1、線程A更新了資料庫
2、線程B更新了資料庫
3、線程B更新了緩存
4、線程A更新了緩存
這就出現請求A更新緩存應該比請求B更新緩存早才對,但是因為網絡等原因,B卻比A更早更新了緩存。這就導緻了髒資料,是以不考慮。
2.業務考慮
1、如果是一個寫多讀少的場景,那麼就會導緻資料壓根沒有讀到,緩存就被頻繁的更新。
2、如果寫入資料庫的值,并不是直接寫入緩存的,而是要經過一系列的計算再寫入緩存,那麼,每次寫入資料庫後,都再次計算寫入緩存的值。
先删除緩存,再更新資料庫
1.問題
同時有一個請求A進行更新操作,另一個請求B進行查詢操作,那麼會出現這種情況: 1、請求A進行寫操作,删除緩存 2、請求B查詢發現緩存不存在
3、請求B去查詢資料庫得到舊值 4、請求B将舊值寫入緩存 5、請求A将新值寫入資料庫
這種其實可以通過設定過期時間解決,如果不設定,可以用延時雙删政策
1、先删除緩存
2、再寫資料庫
3、休眠一秒,再删除緩存。這樣就可以把這一秒内産生的髒資料,再次删除。
先更新資料庫,再删除緩存
假設這會有兩個請求,一個請求A做查詢操作,一個請求B做更新操作,那麼會有如下情形産生:
1.緩存剛好失效
2.請求A查詢資料庫,得一個舊值
3.請求B将新值寫入資料庫
4.請求B删除緩存
5.請求A将查到的舊值寫入緩存 ok,如果發生上述情況,确實是會發生髒資料。
然而,發生這種情況的機率又有多少呢?
發生上述情況有一個先天性條件,就是步驟(3)的寫資料庫操作比步驟(2)的讀資料庫操作耗時更短,才有可能使得步驟(4)先于步驟(5)。可是,大家想想,資料庫的讀操作的速度遠快于寫操作的(不然做讀寫分離幹嘛,做讀寫分離的意義就是因為讀操作比較快,耗資源少),是以步驟(3)耗時比步驟(2)更短,這一情形很難出現。
是以,cache aside采用了先更新資料庫,再删除緩存的方案。
總結
以上介紹了三種經典的緩存模式,同時分析了三種資料更新方案存在的問題和優缺點。