在現代 Web 應用程式開發中,快取是提升應用程式效能不可或缺的技術。在過去,我們會使用 IMemoryCache 做記憶體快取,或者使用 IDistributedCache 做分散式快取。
.NET 9 引入了全新的 HybridCache,它結合了記憶體快取(L1)和分散式快取(L2)的優勢,讓我們能夠在同一個 API 中享受兩層快取的效能提升,同時還提供了快取雪崩保護和標籤管理等進階功能。

開發環境
- Windows 11 Pro
- ASP.NET Core 9.0
- Microsoft.Extensions.Caching.Hybrid
- Microsoft.Extensions.Caching.StackExchangeRedis
- Rider 2025.2
HybridCache 是什麼?
HybridCache 是 .NET 9 中新推出的快取程式庫,透過 Microsoft.Extensions.Caching.Hybrid 套件提供。它被稱為「混合快取」,因為能夠同時利用記憶體內快取(L1)和分散式快取(L2,如 Redis)來最佳化資料儲存和檢索效能。
雙層快取架構(L1/L2)
- L1 快取:運行在應用程式記憶體中,提供最快的存取速度
- L2 快取:可以是 Redis、SQL Server 或任何其他分散式快取
- 彈性配置:可以只使用 L1 快取,無需分散式快取
- 避免快取雪崩(Stampede)
- HybridCache 確保對於相同的鍵值,只有一個並發呼叫者會執行工廠方法,其他呼叫者等待該結果,防止快取雪崩問題。
- 支援標籤式快取管理
- 提供自訂序列化器
- 預設使用 System.Text.Json 處理字串和 byte[]
- 支援透過 WithSerializer 和 WithSerializerFactory 方法自訂序列化器
- 可配置為使用 protobuf 或 XML 等其他序列化器
架構圖:
graph TB
A[應用程式請求] --> B[HybridCache]
B --> C[L1 記憶體快取]
C --> D{命中?}
D -->|是| E[直接回傳]
D -->|否| F[L2 分散式快取]
F --> G{命中?}
G -->|是| H[回傳並存入L1]
G -->|否| I[執行資料來源]
I --> J[存入L1與L2]
J --> K[回傳結果]

如何安裝?
dotnet add package Microsoft.Extensions.Caching.Hybrid
如果你要用 Redis 當 L2 快取:
dotnet add package Microsoft.Extensions.Caching.StackExchangeRedis
基本設定
只使用 L1 快取:
builder.Services.AddHybridCache();
使用 Redis 作為 L2 快取:
builder.Services.AddStackExchangeRedisCache(options =>
{
options.Configuration = "localhost:6379";
});
builder.Services.AddHybridCache(options =>
{
options.DefaultEntryOptions = new HybridCacheEntryOptions
{
Expiration = TimeSpan.FromMinutes(5),
LocalCacheExpiration = TimeSpan.FromMinutes(1)
};
});
快取資料的方式
在應用程式端,挖一個洞讓物件依賴 Microsoft.Extensions.Caching.Hybrid.HybridCache
var weather = await _cache.GetOrCreateAsync(
key: $"weather-{city}",
factory: async token =>
{
await Task.Delay(1000, token); // 模擬外部 API
return new WeatherInfo(city, 28, "晴朗", DateTime.UtcNow);
},
options: new HybridCacheEntryOptions
{
Expiration = TimeSpan.FromMinutes(10),
LocalCacheExpiration = TimeSpan.FromMinutes(2)
},
tags: [$"weather-{city}"]);
這段程式碼會先查 L1,再查 L2,最後才執行 factory 方法。這樣可以避免重複查詢外部資源。
NOTE:L1 快取時間應比 L2 短
我的範例則是在 Minimal Api 方法注入 Microsoft.Extensions.Caching.Hybrid.HybridCache
app.MapGet("/weatherforecast/hybrid-cache",
async (Microsoft.Extensions.Caching.Hybrid.HybridCache hybridCache) =>
{
// 使用 HybridCache 快取天氣預報資料
var forecast = await hybridCache.GetOrCreateAsync(
key: "weather-forecast",
factory: async cancellationToken =>
{
// 模擬從資料來源獲取資料(這裡會有延遲以便觀察快取效果)
await Task.Delay(TimeSpan.FromMicroseconds(2), cancellationToken); // 模擬 2 秒的資料庫查詢
Console.WriteLine($"[{DateTime.Now:HH:mm:ss}] 從資料來源生成天氣預報資料");
return Enumerable.Range(1, 5).Select(index =>
new WeatherForecast
{
Date = DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
TemperatureC = Random.Shared.Next(-20, 55),
Summary = summaries[Random.Shared.Next(summaries.Length)]
})
.ToArray();
},
tags: ["weather-forecast"]
);
return Results.Ok(new
{
Data = forecast,
CachedAt = DateTime.Now,
Message = "資料來自 HybridCache (L1: 記憶體 + L2: Redis)"
});
})
.WithName("GetWeatherForecastWithHybridCache")
.WithSummary("使用 HybridCache 的天氣預報")
.WithDescription("展示 HybridCache L1(記憶體)+ L2(Redis)雙層快取功能");
標籤式快取管理
HybridCache 支援快取標籤,方便批次清除:
await _cache.RemoveByTagAsync("product-123");
await _cache.RemoveByTagAsync("category-electronics");
這在產品更新、類別變動時非常實用。
自訂序列化器
預設使用 System.Text.Json,但你可以改用 protobuf:
options.WithSerializerFactory(type =>
{
if (type == typeof(Product))
return new ProtobufSerializer<Product>();
return null;
});
心得
HybridCache 是 .NET 9 中一個非常實用的快取工具,它讓我們不再需要在記憶體快取與分散式快取之間做選擇。透過簡單的 API、標籤管理、自訂序列化器等功能,讓快取管理變得更簡單、更彈性。
- L1 快取時間應比 L2 短
- 所有快取都加上標籤,方便日後清除
參考資料
- Microsoft Learn - HybridCache library in ASP.NET Core
- .NET Blog - HybridCache 官方介紹
- Microsoft.Extensions.Caching.Hybrid NuGet
範例位置
sample.dotblog/Cache/Lab.HybridCache at master · yaochangyu/sample.dotblog
若有謬誤,煩請告知,新手發帖請多包涵
Microsoft MVP Award 2010~2017 C# 第四季
Microsoft MVP Award 2018~2022 .NET