為了程式效率,通常會利用記憶體存取速度遠高於磁碟讀取的特性,把常用但不常變動資料放在記憶體中,提升取用資料的速度。ASP.NET Core 有提供好用的快取機制,不用自己實作控制資料的快取物件。
本篇將介紹 ASP.NET Core 的本機快取及分散式快取,並用使用分散式快取實作 Redis Session,避免 Web Application 重啟後,用戶要重新登入。
iT 邦幫忙 2018 鐵人賽 - Modern Web 組參賽文章:
[Day20] ASP.NET Core 2 系列 - 快取機制及 Redis Session
本機快取
本機快取是比較基本的資料快取方式,將資料存在 Web Application 的記憶體中。
如果是單一站台架構,沒有要同步快取資料,用本機快取應該都能滿足需求。
使用本機快取的方式很簡單,只要在 Startup.ConfigureServices
呼叫 AddMemoryCache
,就能透過注入 IMemoryCache
使用本機快取。如下:
Startup.cs
1 | public class Startup |
Controllers\HomeController.cs
1 | using Microsoft.Extensions.Caching.Memory; |
用 Get
/Set
方法,就可以透過 Key 做為取值的識別,存放任何型別的資料。
分散式快取
當 ASP.NET Core 網站有橫向擴充,架設多個站台需求時,分散式快取就是一個很好的同步快取資料解決方案。
基本上就是 NoSQL 的概念,把分散式快取的資料位置,指向外部的儲存空間,如:SQL Server、Redis 等等。只要繼承 IDistributedCache
,就可以被當作分散式快取的服務使用。
本機快取及分散式快取架構,如圖:
在 Startup.ConfigureServices
注入 IDistributedCache
使用分散式快取。如下:
Startup.cs
1 | public class Startup |
- AddDistributedMemoryCache
是透過實作分散式快取的介面IDistributedCache
,將資料存於本機記憶體中。
Controllers\HomeController.cs
1 | using Microsoft.Extensions.Caching.Distributed; |
IDistributedCache
的 Get
/Set
不像 IMemoryCache
可以存取任意型別,IDistributedCache
的 Get
/Set
只能存取 byte[]
型別,如果要將物件存入分散式快取,就必須將物件轉換成 byte[]
型別,或轉成字串型別用 GetString
/SetString
存取於分散式快取。
如果要將物件透過
MemoryStream
序列化,記得在物件加上[Serializable]
。
Redis Session
[鐵人賽 Day11] ASP.NET Core 2 系列 - Cookies & Session 有用到 AddDistributedMemoryCache
,由於 Session 的儲存位置是依賴分散式快取,但沒有外部分散式快取可用,所以用繼承 IDistributedCache
的本機分散式快取頂著。
安裝套件
如果要在 ASP.NET Core 中使用的 Redis Cache,可以安裝 Microsoft 提供的套件 Microsoft.Extensions.Caching.Redis.Core
。
透過 .NET Core CLI 在專案資料夾執行安裝指令:
1 | dotnet add package Microsoft.Extensions.Caching.Redis.Core |
設定 Redis Cache
安裝完成後,將 Startup.ConfigureServices
註冊的分散式快取服務,從 AddDistributedMemoryCache
改成 AddDistributedRedisCache
。如下:
Startup.cs
1 | public class Startup |
這樣就完成將分散式快取指向 Redis Cache,Session 的註冊方式同 **[Day11]**。
只要設定 AddDistributedRedisCache
就可以使用 Redis Session 了,輕鬆簡單。
ASP.NET MVC 比較
ASP.NET Core 的 Redis Session 跟 ASP.NET MVC 普遍用的 StackExchange.Redis
的運行方式有很大的差異。
ASP.NET MVC Redis Session
StackExchange.Redis
在使用 Redis 時,是把 Website 的 Session 備份到 Redis,讀取還是在 Website 的記憶體,寫入的話會再度備份到 Redis。
也就是說 Session 會存在於 Website 及 Redis Cache 中,HA 的概念。
可以試著把 Redis Cache 中 Session 清掉,當使用者下一個 Requset 來的時候,又會重新出現在 Redis Cache 中。
運行方式如下圖:ASP.NET Core Redis Session
IDistributedCache
運作方式變成 Session 直接在 Redis Cache 存取,如果把 Redis Cache 中 Session 清掉,當使用者下一個 Requset 來的時候,就會發現 Session 被清空了。
運行方式如下圖:
參考
In-memory caching in ASP.NET Core
Working with a distributed cache in ASP.NET Core