Aaron Li

Redis: Cache

Table of Content

為什麼要做 cache ?

做 cache 的主要目的是提高資料存取的速度和效率。當程式需要頻繁地存取某些資料時,從記憶體或 cache 中獲取資料比從磁碟或遠端伺服器中取得資料要快得多。這樣可以減少對資源的重複訪問,提高系統的回應速度,並且減輕了伺服器或資料庫的負載。

Cache 的原理

1. Client 向 Application 發送請求
2. Application 先向 Redis 查詢資料 
3. Redis Cache miss, 向 DB 查詢資料
4. Application 回傳資料給 client, 並存在 Redis 裡
(資料可能在 redis 也可能在 db, 怎麼能達到數據的一致性呢?)

Client --1---> Application -----(效能瓶頸)--3--> Database (磁盤)
                                |
                                |--2---> Redis Cache (內存)

Cache 的優缺點

  • 優點
  1. 提升 Application 的性能
  2. 減輕 DB 的負擔
  3. 可擴展性提升 (多節點的 redis 比 多節點的其他關係資料庫成本低)
  • 缺點
  1. 增加 Application 的複雜度
  2. 資料一致性問題
  3. 維運成本提高

Cache 的策略

Cache-Aside (Lazy Loading) Pattern

  • 讀: 應用程式首先在 cache 中尋找資料的模式。如果未找到數據,它會從 DB 獲取數據,將其儲存在 cache 中,然後返回給用戶 (已資料庫的資料為準)
  Application ---1. 嘗試從 cache 找  ------ 2. 若沒有找到則從 DB 找 ------>  DB
                                      |                                    |
                                      |                                    |
                                    Cache <------- 3. 存進 cache ----------
  • 寫: 更新在資料庫裡的資料,然後刪除在 cache 裡的舊資料
  Application ------- 1. 直接更新 DB 的資料  ------>  DB
                                                      |
                                                      |
Cache <------- 2. 刪除 在 cache 的舊資料(不更新) ----
  • 適合資料變更不頻繁,沒有高併發熱點 key (熱點 key 在寫時會刪除 cache,此時 DB 會突然收到 此key 的大量請求)
  • 第一次請求一定是 cache miss (可以先把熱點 key 先存進 cache)
  • 若是更新 cache 的資料的話在 併發寫 的時候可能會數據不一致
  • 若是先更動 cache 在更動資料庫的話在 讀寫併發 的時候會數據不一致, EX:

Request A ---------- write A to 2
                          |
DB: {A: 1}  ------------{A: 2} -----
                                    | delete key A
Cache: {A: 1} --------------------- {}
                                |
Request B --------------------Read A and get 1

Write/Read-Through Pattern

application 只需跟 cache 進行讀寫, 將同步 DB 的職責轉給 cache provider

  • 讀: 先查 cache, 命中則回傳,若 miss 則 cache provider 向 DB 取得資料,並存進 cache 然後回傳給 user
application ----- 1. query data ---> redis  ------ 2. get data ---> DB
                    4. return -----         <----  3. set cache
  • 寫: 將資料寫入 cache, 由 cache provider (redis) 同步到 DB
Application ------  1. write data  --->  redis --- update data ----> db

Write-Behind (Write-Back) Pattern

跟 Write-Through Pattern 差不多,但更新並不會立刻到 DB,而是會稍後將 batch 的操作合併並更新 DB

  • 因為不會立刻同步資料庫,所以在之間若 cache down, 則會丟失數據
  • 適合對數據一致性不要求的場景
  • 適合頻繁更新的場景