ASP.NET 提供 Session 與 Cache 兩種伺服器端儲存機制,雖同屬記憶體存儲,但設計初衷、生命週期、適用場景截然不同。本文從五大維度深度對比,助你精準選型。
| 維度 | Session | Cache |
|---|---|---|
| 1. 資料範圍 | 單一使用者會話隔離 | 全應用程式共享(所有使用者可見) |
| 2. 失效機制 | 僅支援滑動過期(預設 20 分鐘無活動) | 支援絕對過期、滑動過期、檔案/SQL/自定義依賴自動失效 |
| 3. 存活週期 | 會話結束或應用程式重啟即銷毀 | 應用程式重啟後,若未過期資料依然保留(記憶體未回收前) |
| 4. 可靠性 | 易遺失:InProc 模式下 AppPool 回收、Web.config 修改、佈署皆導致 Session 遺失 | 相對穩定:除非記憶體壓力觸發回收或明確移除,否則持續存在 |
| 5. 容量建議 | 不宜存放大量資料(每用戶獨佔記憶體),易導致記憶體暴增 | 專為大容量設計:資料集、報表、共用查詢結果等 |
// 檔案依賴:data.xml 變更即自動移除快取
Cache.Insert("ProductList", ds, new CacheDependency(Server.MapPath("~/App_Data/data.xml")));
// SQL 快取依賴:資料表異動自動失效 (需啟用 aspnet_regsql -et -d DB -t Products)
Cache.Insert("Products", ds, new SqlCacheDependency("DB", "Products"));
Session 完全不支援此機制,只能被動等待逾時。
VS2005 測試版曾支援 Cache 持久化至硬碟,正式版移除。Session 僅支援 InProc/StateServer/SQLServer/Custom,無原生硬碟持久化選項。
資料是否為使用者專屬?
├── 是 → 使用 Session (或加密 Cookie / ClaimsPrincipal)
└── 否 → 資料是否頻繁變動?
├── 是 → 不快取,直接查詢或使用 SignalR 即時推送
└── 否 → 資料量大小?
├── 小型共用資料 (設定、字典表) → Cache (絕對過期 + 檔案依賴)
├── 大型報表/查詢結果 → Cache (滑動過期 + SQL 依賴) 或 Redis 分散式快取
└── 跨伺服器叢集共享 → 必須使用 StateServer/SQLServer Session 或 Redis/Memcached
StateServer 或 SQLServer 模式避免遺失。CacheHelper 封裝 Insert/Get/Remove,統一命名慣例(如 CacheKeys.ProductList_{0}),記錄快取命中率日誌。Session 解決「誰是誰」的狀態識別,Cache 解決「資料怎麼快」的效能提升。理解兩者邊界,配合快取依賴實現資料變更自動失效,才是打造高效能、高可用 ASP.NET 應用的正確姿勢。