---
# System prepended metadata

title: 快取(Cache)機制 - 筆記
tags: [cache, Interview Preparation, database]

---

# 快取(Cache)機制 - 筆記

###### tags: `cache` `database` `Interview Preparation` `scalibility`
:::warning
:bulb: 本站筆記已同步更新到我的[個人網站](https://simplydevs.netlify.app/)囉! 歡迎參觀與閱讀，體驗不同的視覺感受!
:::
[TOC]

## :memo: 什麼是快取(Cache)
當web app規模越來越大、使用者越來越多，頁面加載的時間也變得更久；因此，需要一個更快速的方式提供網站內容給使用者。快取提供了這種功能，快取指的是將資料儲存在具有高速特性的資料儲存層的一個過程，尤其針對可重複使用的資料，後續發送請求這些資料時，可以更有效率地重複使用之前擷取或運算過的資料。

## :memo: 快取的好處與使用情境

### 好處
* **提高性能(performance)：**
**經由快取解析的請求，能夠快速地從快取中取得資料(對應的response)，稱為快取命中(cache hits)。** 快取優先儲存需要高頻率取得的資料，減少需要重複從較慢速的儲存資源中(如硬碟)重複取得資料的需求，因此使用者發送出的請求可以更高效率的被解析。
* **減少伺服器流量負載(traffic load)：**
 同樣的請求(例如網站首頁的商品圖)如果短時間內大量發送(如同時數百個使用者上線)，這樣的流量會造成伺服器的負擔；如果把這些圖片透過快取機制讀取，可以提升使用者獲得回應的速度，同時避免伺服器浪費效能處理重複的請求。
* **改善資料庫性能：**
研究指出，獲得伺服器回應(response)的時間中，很大一部份都花在等待資料庫回應；即使資料庫查詢指令是高效率的，處理每個指令(尤其是需要頻繁取得的物件)也會快速增加時間成本。解決此問題的一個方法是繞過指令處理，使用預先計算過的快取解果。
* **提高內容的可用性(availability)：**
即使原始資料庫暫時關閉，快取也可以用作保留某些資料可用性的一種方式。

### 使用情境
![](https://hackmd.io/_uploads/BJKz3h332.png)
<div style="text-align:center;">
HTTP Web App的分層(layer)<br>
    
圖片來源：[AWS](https://aws.amazon.com/tw/caching/?nc1=h_ls)
</div>

常見應用快取的分層：
#### **客戶端層快取:**
在用戶端的平台應用快取，例如瀏覽器快取。大多數瀏覽器都有一個內建的小型快取，允許Web app儲存頁面和資料的臨時副本（例如圖像、臨時數據），以便用戶不必多次檢索相同的資訊。然而，開發者對這種類型的快取的控制能力最少，因為它的功能（例如大小、速度）由維護瀏覽器的公司（例如Google Chrome、Firefox）管理；另外因為現代使用者常透過多平台(web, Android app, iOS app等)互動，若在客戶端實作快取，則必須製作多種不同快取，維護成本較高。
#### **DNS層快取：**
DNS將網域解析至IP位置，因此DNS快取旨在減少DNS伺服器查詢IP時所花費的時間，將作業系統或瀏覽器中所取得的歷史網域記錄存入快取，下次解析同樣網域時，就可從快取中取得解析結果，不需重複詢問DNS伺服器。
#### **Web content層快取：**
加速從 Web/應用程式伺服器擷取 Web 內容，如圖片等，管理 Web工作階段 (伺服器端)。常見的如CDN(Content Delivery Network)快取、反向代理伺服器等。
#### **應用程式層快取：**
應用程式層快取是應用在伺服器端的快取。我們可以使用應用程式層快取來儲存瀏覽器內容或類似的數據。這種類型的快取可以幫助緩解高流量期間的伺服器壓力。與客戶端層快取不同，系統管理者對應用程式層快取有較高的控制能力。
#### **資料庫層快取：**
資料庫層快取可以儲存最近的資料庫查詢及其對應的回應，以幫助提高查詢回應速度，降低與資料庫查詢請求相關的延遲。資料庫層快取還可以減少資料庫使用並在資料庫發生故障時，提供部分數據可用性。

## :memo: 快取置換策略(Cache Eviction Policies / Cache Replacement Policies)
為了使快取更有效，我們希望能夠將快取命中(cache hits)極大化，並減少快取失誤(cache miss)；也就是希望當請求傳入時，盡可能提高從快取中回傳資料的機率。而因為快取的生產和購買成本高，快取的小尺寸也限制了我們可以存的資料量，因此，需要考慮隨著時間的推移，應該保留或刪除哪些數據，也就是當快取滿了該如何處理。這是**快取置換策略(Cache Eviction Policy)** 的核心目的，這些策略是用於管理快取中資料的**演算法**。

:pushpin: 常見的策略/演算法：
### **LRU (Least Recently Used):**
LRU會**替換/移除最長時間未發送請求的項目**，根據上次使用的時間戳計，**最久沒被存取的快取資料會先被移除**，才有空間放入新的資料。每次發送請求時，LRU演算法都會更新該請求對象的時間戳，並將其**移至快取頂部**；當需要從快取中移除某些項目時，它將分析快取的狀態並**刪除列表底部的項目**。
### **Most Recently Used (MRU):**
MRU策略**本質上與LRU相反**，它也是根據快取上次訪問的時間來決定先被移除的快取資料，但它和LRU的不同之處在於，它從快取中**移除最近造訪的對象**，而不是最近最少使用的對象。
MRU在以下情境十分實用：當一個快取項目越久沒被使用，他就越有可能在接下來被使用（換句話說，最近被使用的對象，不可能很快再次被使用）。例如，預訂航班座位後，立即從快取中刪除該預訂的座位，因為它們不再與後續的預訂相關。
### **Least Frequently Used (LFU):**
LFU將**刪除自存入快取以來最少使用的項目**。LFU透過在每次存取快取對象時**計數**來執行分析，以便在需要從快取中移出項目時與其他對象進行比較。LFU在快取對象的訪問模式不經常變動的情況下表很實用，並且相較於MRU或LRU，儲存計數比儲存時間戳記消耗更少的記憶體。
然而，當某個項目被頻繁使用之後，使用次數急遽下降時，LFU會造成該項目被卡在快取中不會消失(儘管已經不再被使用)，而新加入或使用次數低的資料則不斷在變動。
### **FIFO (First In First Out):**
FIFO策略會**按照項目被放入快取中的順序移除**，也就是最先加入的資料，在快取滿的時候，會優先被移除，而不考慮它們被使用的頻率或次數。


## 小結
以上簡單介紹快取及常見的置換策略，更多策略可以參考[Wikipedia](https://en.wikipedia.org/wiki/Cache_replacement_policies#Policies)。




---

## 參考資料
* [快取概觀-AWS](https://aws.amazon.com/tw/caching/?nc1=h_ls)
* [極限加速！Web 開發者不能不知道的 Cache 大補帖！](https://oldmo860617.medium.com/%E6%A5%B5%E9%99%90%E5%8A%A0%E9%80%9F-web-%E9%96%8B%E7%99%BC%E8%80%85%E4%B8%8D%E8%83%BD%E4%B8%8D%E7%9F%A5%E9%81%93%E7%9A%84-cache-%E5%A4%A7%E8%A3%9C%E5%B8%96-3c7a9c4241de)
* [Caching In Node.js Applications](https://www.honeybadger.io/blog/nodejs-caching/)
* [快取的置換策略(Cache replacement policies)](https://myapollo.com.tw/blog/interview-question-cache-replacement-policies/)
* [[不是工程師] 讓網站速度飛快的秘密，你了解什麼是網頁快取(Cache)嗎?](https://progressbar.tw/posts/93)
* [什麼是快取 (Cache)？快取 (Cache) 的機制為何？](https://www.explainthis.io/zh-hant/interview-guides/backend/cache-mechanism)
* [提升程式存取資料速度的必殺技](https://www.ithome.com.tw/voice/67234)


::: success
:crescent_moon: 　本站內容僅為個人學習記錄，如有錯誤歡迎留言告知、交流討論！
:::

