怎樣使用主流快取更新策略來減少效能消耗?
在網際網路專案開發中,快取的應用是非常普遍了,快取可以幫助頁面提高載入速度,減少伺服器或資料來源的負載。
一、為什麼需要快取?
一般在專案中,最消耗效能的地方就是後端服務的資料庫了。而資料庫的讀寫頻率常常都是不均勻分佈的,大多情況是讀多寫少,並且讀操作(select)還會有一些複雜的判斷條件,比如like、group、join等等,這些語法是非常消耗效能的,所以會出現很多的慢查詢,因此資料庫很容易在讀操作的環節遇到瓶頸。
那麼通過在資料庫前面,前置一個快取服務,就可以有效的吸收不均勻的請求,抵擋流量波峰。
另外,如果應用與資料來源不在同一個伺服器,中間還會有很多的網路消耗,也會對應用的響應速度有很大影響,如果當前應用對資料實時性的要求不那麼強的話,在應用側加上快取就能很快速地提升效率。
二、使用快取會遇到哪些問題?
雖然快取可以提高整體效能,但是它也可能會帶來別的問題。
例如使用快取之後,就相當於把資料存放了2份,一份是在資料庫中,另一份存放在快取中。當有新的資料要寫入或者舊資料需要更新的時候,如果我們只更新了其中一份資料來源,那兩邊的資料就不一致了。所以這裡就存在一個快取資料與資料庫資料如何進行有效且快速的同步才可以保證資料最終一致性的問題。
另外,加上快取服務其實也引入了系統架構的複雜度,因為還需要額外的關注快取自身帶來的下列問題:
1、快取的過期時間問題
設計快取的過期時間非常需要有技巧,且必須與業務實際情況相結合。因為如果設計的過期時間太短了,那會導致快取效果不佳,而且還會造成頻繁的從資料庫中往快取裡寫資料;如果快取設計的過期時間太長了,又會導致記憶體的浪費。
2、快取的命中率問題
這也是設計快取中需要存放哪些資料的很重要一點。如果設計的不好,可能會導致快取命中率過低,失去快取效果。一般對於熱點資料而言,要保證命中率達到70%以上效果最佳。
3、快取的穿透/雪崩問題
穿透/雪崩問題是指如果快取服務一旦宕機或全部丟失,那麼有可能一瞬間所有的流量都直接打到了後端資料庫上,可能會造成連鎖反應,瞬間的請求高峰極有可能導致資料庫無法承載。
三、快取的更新策略具體有哪些?
典型的快取模式,一般有如下幾種:
-
Cache Aside;
-
Read/Write Through;
-
Write Behind。
每種模式都有不同的特點,適用於不同的專案場景,下面來依次看看:
1、Cache Aside模式
這是大家經常用到的一種策略模式。這種模式主要流程如下:
-
應用在查詢資料的時候,先從快取Cache中讀取資料,如果快取中沒有,則再從資料庫中讀取資料,得到資料庫的資料之後,將這個資料也放到快取Cache中;
-
如果應用要更新某個資料,也是先去更新資料庫中的資料,更新完成之後,則通過指令讓快取Cache中的資料失效。
這裡為什麼不讓更新操作在寫完資料庫之後,緊接著去把快取Cache中的資料也修改了呢?
主要是因為這樣做的話,就有2個寫操作的事件了,擔心在併發的情況下會導致髒資料,舉個例子:
假如同時有2個請求( 請求A和請求B )併發的執行。請求A是要去讀資料,請求B是要去更新資料。初始狀態快取中是沒有資料的,當請求A讀到資料之後,準備往回寫的時候,此刻,請求B正好要更新資料,更新完了資料庫之後,又去把快取更新了,那請求A再往快取中寫的就是舊資料了,屬於髒資料。
那麼Cache Aside模式就沒有髒資料問題了嗎?不是的,在極端情況下也可能會產生髒資料,比如:
假如同時有2個請求( 請求A和請求B )併發的執行。請求A是要去讀資料,請求B是要去寫資料。假如初始狀態快取中沒有這個資料,那請求A發現快取中沒有資料,就會去資料庫中讀資料,讀到了資料準備寫回快取中,就在這個時候,請求B是要去寫資料的,請求B在寫完資料庫的資料之後,又去設定了快取失效。這個時候,請求A由於在資料庫中讀到了之前的舊資料,開始往快取中寫資料了,此時寫進入的就也是舊資料。那麼最終就會導致,快取中的資料與資料庫的資料不一致,造成了髒資料。
不過這種概率比上面一種概率要小很多。所以整體而言Cache Aside模式還是一種比較簡單實用的方式。
2、Read/Write Through模式
這個模式其實就是將快取服務作為主要的儲存,應用的所有讀寫請求都是直接與快取服務打交道,而不管最後端的資料庫了,資料庫的資料由快取服務來維護和更新。不過快取中資料變更的時候是同步去更新資料庫的,在應用的眼中只有快取服務。
流程就相當簡單了:
-
應用要讀資料和更新資料都直接訪問快取服務;
-
快取服務同步的將資料更新到資料庫。
這個模式出現髒資料的概率就比較低,但是就強依賴快取了,對快取服務的穩定性有較大要求。另外,增加新快取節點時還會有初始狀態空資料問題。
3、Write Behind模式
這個模式就是Read/Write Through模式的一個變種。區別就是Read/Write Through模式的快取寫資料庫的時候是同步的,而Write Behind模式的快取操作資料庫是非同步的。
流程如下:
-
應用要讀資料和更新資料都直接訪問快取服務;
-
快取服務非同步的將資料更新到資料庫(通過非同步任務)。
這個模式的特點就是速度很快,效率會非常高,但是資料的一致性比較差,還可能會有資料丟失的情況,實現邏輯也較為複雜。
以上就是目前三種主流的快取更新策略,另外還有Refrsh-Ahead模式等由於使用的不是很常見就不詳細介紹了。
快取是網際網路專案中非常普遍的一個提高效率的方案,用法比較多,也比較關鍵,大家可以一起交流。
作者: IVAN-jsjwk
來源:不止思考訂閱號(ID:bzsikao)
dbaplus社群歡迎廣大技術人員投稿,投稿郵箱:[email protected]