## 1) 為何要系統性學習 Redis 快取 - 由於 Redis **作為快取的普遍性**與其在業務應用中的重要性,我們需要**系統地**掌握: - **工作原理** - **替換策略** - **異常處理** - **擴展機制** - 需要解決的四個關鍵問題: 1. **Redis 快取具體是怎麼工作的?** 2. **Redis 快取如果滿了,該怎麼辦?** 3. **為什麼會有快取一致性、快取穿透、快取雪崩、快取擊穿等異常,該如何應對?** 4. **Redis 記憶體有限;若使用快速固態硬碟保存資料以增加快取量,Redis 快取可以使用 SSD 嗎?** --- ## 2) 快取的特徵(為何需要、為何適合) - **不同層級的存取速度不同**,因此需要快取:把**需要頻繁訪問的資料**放在**更快**的一層,以加速存取。 - 以**電腦系統的三層儲存**做比喻: - **最上層:處理器(含暫存器 / CPU 快取)** → 速度最快、容量最小 - **中間:主記憶體(RAM)** → 速度中等、容量中等 - **最下層:磁碟(SSD/HDD)** → 速度最慢、容量最大 - 由上而下:**速度遞減、容量遞增**。快取的核心思路:**用小而快的層緩衝大而慢的層**。 > 圖示(文字示意): > 處理器(快・小) → 記憶體(中) → 磁碟(慢・大) ![截圖 2025-08-13 晚上9.08.45](https://hackmd.io/_uploads/HJYwR-5_ee.png) --- ## 3) 系統中的兩種預設快取 - **CPU 末級快取(LLC)**:快取「記憶體中的資料」,避免每次都從記憶體讀寫。 - **記憶體中的頁面快取(page cache)**:快取「磁碟中的資料」,避免每次都從磁碟讀寫。 --- ## 4) 速度關係 - 與記憶體相比:**LLC 更快**。 - 與磁碟相比:**記憶體更快**。 --- ## 5) 快取的第一個特徵 在**層次化系統**中,**快取一定是較快的子系統**。當資料存在快取中時,能避免每次都從**較慢的子系統**讀寫。 --- # Redis 快取處理請求的兩種情況 ![截圖 2025-08-14 上午10.02.56](https://hackmd.io/_uploads/H1hA7a5dlg.png) ## 1) 部署與讀取順序 - 將 Redis 作為快取時,會**部署在資料庫的前端**。 - 業務應用在讀取資料時,會**先查詢 Redis** 是否已有對應資料。 ## 2) 兩種情況 - **快取命中**:Redis 中**有相應資料**,直接讀取 Redis,**效能非常快**。 - **快取缺失**:Redis 中**沒有相應資料**,需要從**後端資料庫**讀取,**效能較慢**。 ## 3) 缺失後的快取更新 - 一旦發生快取缺失,為了讓**後續請求**能直接從快取讀取,需要將**缺失的資料寫入 Redis**,此過程稱為**快取更新**。 - 快取更新會牽涉到**快取與資料庫之間的一致性**問題(將在第 25 講中介紹)。 ![截圖 2025-08-13 晚上9.17.09](https://hackmd.io/_uploads/rJbDlz9Oel.png) ## 4) 三個基本操作 使用 Redis 作為快取時,基本包含三件事: 1. 應用在讀取資料時,**需要先讀取 Redis**。 2. 發生快取缺失時,**需要從資料庫讀取資料**。 3. 發生快取缺失時,**還需要更新快取**(將缺失的資料寫入 Redis 以供後續讀取)。 # Redis 作為旁路快取的使用操作 ## 1) 為何稱為「旁路快取」 - **Redis 與業務應用是兩個獨立軟體**;部署 Redis 後,它**被動等待**客戶端請求再處理。 - 若應用要使用 Redis 快取,必須在程式中**新增快取操作的程式碼**。 - 因此,「讀取快取、讀取資料庫、更新快取」**都在應用程式內完成**,這與硬體層面的快取不同。 ## 2) 與 LLC / page cache 的差異 - 平時開發程式時,**不會顯式建立 LLC 或 page cache 的實例**,也**不會顯式呼叫它們的 GET 介面**。 - 這是因為在硬體系統建構時,**LLC 與 page cache 已置於資料存取路徑上**,應用程式**直接就能用到**。 - **Redis 則不同**:要用就必須**在應用程式中顯式呼叫其 API**。 ## 3) 需要新增的三類程式碼 1. 當應用需讀取資料時:**顯式呼叫 Redis 的 GET** 查詢。 2. 若發生快取缺失:**再與資料庫連線**,自資料庫讀取資料。 3. 當快取中的資料需要更新時:**顯式呼叫 SET**,把更新後的資料寫入快取。 ## 4) 適用性與限制 - 因為需要新增程式碼來使用快取,**不適用於無法取得原始碼的應用**: - 很早之前開發、已不再維護的程式; - 第三方供應商開發且未提供原始碼的應用。 - 使用旁路快取會**增加額外工作量**,但也因 Redis 是獨立系統,**可單獨對其擴容或做效能優化**。 - 只要**操作介面不變**,**應用中新增的程式碼就無需再修改**。 ## 5) 快取型別的引入 - 除了從 Redis 查詢/讀取,**應用也可能修改資料**:可在快取中修改,或在後端資料庫中修改。 - 這引出兩種快取型別: - **只讀快取**:能加速讀取請求; - **讀寫快取**:可同時加速讀與寫。 - 且**讀寫快取**有**兩種資料寫回策略**,可根據業務需求在**效能**與**資料可靠性**間做選擇。 # 快取的類型:只讀快取與讀寫快取 ## 1) 類型劃分 - 依據 Redis 快取是否接受**寫請求**,可分為:**只讀快取**與**讀寫快取**。 ## 2) 只讀快取 - **讀取**:應用程式先呼叫 **Redis 的 GET** 介面查詢是否存在;命中則直接從快取讀取。 - **寫入 / 刪改**:所有**寫請求**直接發往**後端資料庫**(在資料庫中增刪改)。 - **與快取的配合**:對於已被 Redis 快取的資料,當在資料庫中刪改後,應用需**刪除 Redis 中對應的快取**; 再次讀取該資料時會發生**快取缺失**,應用自資料庫讀出並**寫回 Redis**,以便後續可直接從快取讀取。 - **例子(資料 A)**: 1. 業務要修改 **A**,且 **A** 在 Redis 中已被快取; 2. 應用先在**資料庫**修改 **A**,並**刪除 Redis 中的 A**; 3. 之後讀取 **A** 時發生**快取缺失**,應用自資料庫讀取 **A** 並**寫入 Redis**; 4. 後續請求可**直接從快取**讀取 **A**。 - **特點**:最新資料都在**資料庫**,由資料庫提供**可靠性保障**,資料**不會有丟失風險**。 - **適用舉例**:當需要快取**圖片、短影片**等**使用者只讀**的資料時,可使用**只讀快取**。 ![截圖 2025-08-13 晚上9.28.50](https://hackmd.io/_uploads/SyRzXM9Oee.png) ## 3) 讀寫快取 - **讀**:請求會送至快取查詢資料是否存在。 - **寫**:**寫請求也會送至快取**,在快取中直接進行**增刪改**。 - **效能表現**:得益於 Redis 的高效存取,增刪改可在快取中**快速完成**並**迅速回應**應用。 - **風險**:最新資料位於**Redis(記憶體資料庫)**;一旦掉電或宕機,**記憶體資料可能丟失**, 因而**最新資料可能遺失**,對業務產生風險。 ## 4) 讀寫快取-兩種資料寫回策略 - 依據對**資料可靠性**與**快取性能**的不同要求,讀寫快取可採: - **同步直寫**:優先**保障資料可靠性**; - **異步寫回**:優先提供**快速回應**。 - 學習理解上述兩種策略,有助於**依業務需求做出正確設計選擇**。 # 讀寫快取的兩種策略:同步直寫與異步寫回 ## a) 同步直寫 - **定義**:寫請求同時發給**快取**與**後端資料庫**處理,等待二者**都寫完**才回覆客戶端。 - **效果**:即使快取宕機或故障,**最新資料仍保存在資料庫**,提供**資料可靠性**保障。 - **代價**:快取處理寫入很快,但需**等待資料庫**完成所有寫請求,**增加回應延遲**、**降低快取訪問效能**。 ## b) 異步寫回 - **定義**:優先考慮**回應延遲**;所有寫請求**先在快取中處理**。當這些增改的資料**被淘汰**時(???????),才**寫回資料庫**。 - **效果**:操作在快取中完成,**速度快**、能迅速回覆應用。 - **風險**:若發生**掉電**且尚未寫回資料庫,**最新資料可能丟失**。 ## 1) 只讀快取 vs 讀寫快取 - **是否需要加速寫請求**是選型關鍵: - 需要加速寫 → 選讀寫快取(指 write-back):前台寫只碰 Redis,寫延遲≈Redis 操作+排隊,DB I/O 被移到背景批次,吞吐提升。代價是最終一致與更高的系統複雜度。 - 寫很少或只想加速讀 → 選只讀快取:把熱查詢結果放 Redis,寫入路徑仍以 DB 為權威;寫時只需「刪鍵或重建」,簡單、安全、成本低。 ## 2) 場景舉例 - **商品大促**:庫存資訊**頻繁修改**;若每次都到資料庫,會拖慢應用 → **讀寫快取**較合適。 - **短影片 App**:影片屬性多但**確定後不常改**;在資料庫修改對快取影響不大 → **只讀快取**較合適。 ![截圖 2025-08-13 晚上9.29.56](https://hackmd.io/_uploads/S1gPmM9deg.png) # 小結 ## 1) 快取的兩個特徵 - 在**分層系統**中,將資料暫存在**快速子系統**有助於**加速存取**。 - **快取容量有限**;當快取**寫滿**時,資料**需要被淘汰**。 ## 2) 為何 Redis 適合作為快取 - Redis **具備高效能存取**與**資料淘汰機制**,符合以上兩個特徵的要求,**非常適合**用作快取。 ## 3) 旁路快取的特性與限制 - Redis 作為**旁路快取**,代表需要在**應用程式中新增快取邏輯**的程式碼。 - 若是**無法修改原始碼**的應用情境,**就不能**使用 Redis 做快取。 ## 4) 快取模式 - **只讀快取**與**讀寫快取**兩種。 - 其中**讀寫快取**提供: - **同步直寫**:**側重資料可靠性**; - **異步寫回**:**側重低延遲**。 - 應依**實際業務需求**進行選擇。