Cache
by Aaron • 10/23/2022, 9:51:42 AM
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 的優缺點
- 優點
- 提升 Application 的性能
- 減輕 DB 的負擔
- 可擴展性提升 (多節點的 redis 比 多節點的其他關係資料庫成本低)
- 缺點
- 增加 Application 的複雜度
- 資料一致性問題
- 維運成本提高
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, 則會丟失數據
- 適合對數據一致性不要求的場景
- 適合頻繁更新的場景