關於快取你需要知道的

2021-08-04 19:32:19 字數 1882 閱讀 7462

作後端開發的同學,快取是必備技能。這是你不需要花費太多的精力就能顯著提公升服務效能的靈丹妙藥。前提是你得知道如何使用它,這樣才能夠最大限度發揮它的功效,並抑制其***。本文將介紹最如何正確的新增和更新快取。

這部分將介紹在開始加快取之前我們必須要做的事情。這步非常重要,如果沒弄好,很有可能加了快取反而不如不加。

為什麼要用快取?對於乙個服務其效能瓶頸往往都在db,傳統關係型儲存尤甚。我們在建立表的時候,並不會未所有的字段建立索引,這意味著如果我們需要讀取非快取資料就要從磁碟拿資料。這個過程至少需要十幾毫秒的時間。而快取往往是基於記憶體的,這要比db讀資料快兩個數量級。這是我們用快取的根本原因原因。

那乾脆把所有的資料扔到記憶體不就行了嘛!不行。記憶體這東西雖然很快,同時它還很貴。動輒百十來g的資料都扔記憶體這有點太浪費。依據二八定律,我們只需找到那最緊俏的百分之二十就行了。這是非常重要的。否則你加了快取效果反而更差。

對於快取有乙個衡量指標,叫做快取命中率。這個指標高說明我們請求的資料大部分來自快取。證明我們加快取這件事的收益越高。

如果你平時都用一些orm工具很可能下邊這些問題你不會直接遇到,不過這些問題都是在你加快取之前需要著實想清楚的。算是一些通用的套路。我們逐條來看一下:

快取穿透是說訪問乙個快取中沒有的資料,但是這個資料資料庫中也不存在。普通思路下我們沒有從資料庫中拿到資料是不會觸發加快取操作的。這時如果是有人惡意攻擊,大量的訪問就會透過快取直接打到資料庫,對後端服務和資料庫做成巨大的壓力甚至宕機。

解決方案:

快取併發這個場景很容易解釋:多個客戶端同時訪問乙個沒有在cache中的資料,這時每個客戶端都會執行從db載入資料set到快取,就會造成快取併發。

解決方案:

快取雪崩是快取服務暫時不能提供服務,導致所有的請求都直接訪問db。

解決方案:

cache-aside-pattern.png

這種思路先更新資料庫,更新成功之後再令快取失效。還有一種方式是先失效快取,然後在更新資料庫。我們來對比一下這兩種方式的不同。

首先,來看後一種。設想一種情景,乙個客戶端發起更新操作,當執行了快取失效。這時乙個讀取操作進來,發現快取沒有資料然後從資料庫拿資料並放到快取。更新操作繼續更新資料庫。這時快取裡已經快取了髒資料。

那麼第一種會出現這種問題嗎?理論上是會的,看一下這個操作:a客戶端發起更新操作,b客戶端發起讀操作,並且這時快取恰好失效,然後它從資料庫載入資料(老資料)。a的更新操作完成失效快取,這時b讀取的客戶端把老資料set到快取。這有這種情況下才會出現髒資料,但是這概率已經非常小了。

read-write-through.png

read through:讀取資料的時候如果當前快取中沒有資料,慣常的操作都是應用程式去db載入資料,然後加入到快取中。read through與之不同的是我們不需要在應用程式自己載入資料了,快取層會幫忙做件事。

write through:更新資料的時候,如果命中快取,則先更新快取然後快取在負責把資料更新到資料庫;如果沒有命中快取則直接更新資料庫。

這種方式快取層直接遮蔽了db,應用程式只需要更快取打交道。優點是應用邏輯簡單了,而且更高效了;缺點是快取層的實現相對複雜一些。

write-back.png

這是三種中實現難度最大的一種方式,它需要乙個專門的儲存儲存快取是否是髒資料,並在讀寫快取時同步髒資料。在資料一致性要求不太高的場景可以使用這種方式。

首先我們來看一下讀快取的操作。如果快取命中直接返回。如果快取沒有命中,則首先去strore中檢索這個key是否dirty,如果不是則載入資料,如果是應先把資料flush到儲存,然後在載入資料。接下來標記這條key為not dirty,返回結果。

寫資料的過程。如果命中快取則更新資料,並標記這條記錄為dirty。如果沒有命中,則去store中檢索這個可以是否dirty,如果不是則從儲存load資料,更新這條資料,如果是則把當前資料flush到儲存,然後load資料更新,並標記這條記錄為dirty。

關於棧,你需要知道這些

分別用四個字描述棧和佇列 棧 後進先出 佇列 先進先出 棧 一種特殊的線性表,其只允許在固定的一端進行插入和刪除元素操作。進行資料插入和刪除操作的一端稱為棧頂,另一端稱為棧底。棧中的資料元素遵守後進先出lifo last in first out 的原則。它的三個核心操作 入棧 棧的插入操作叫做進棧...

(1)關於ROS 你需要知道的

ros的版本名稱是按字母順序e f g h i j k l排列的,electric fuerte groovy hydro indigo jade kinetic lunar.ros的fuerte和groovy版本中會有ros create package和rosmake等命令,而hydro及以後都...

關於機器學習你需要知道的

機器學習著名研究者 pedro domingos 教授寫了篇文章 機器學習那些事 a few useful things to know about machine learning 這是一篇極好的文章,首先作者是在機器學習方面有著深厚功底 非常擅長教人的老師,其次內容豐富全面,更何況他只用了 9 ...