這篇文章講解分佈式緩存,即 Distributed caching in ASP.NET Corenode
分佈式緩存是能夠在多個應用服務上共享的緩存,比較經典的用法是做爲多個應用服務器的一個可到達的外部服務。分佈式緩存能夠提升 ASP.NET Core應用的性能和擴展性(performance and scalability), 特別是當應用是部署在雲服務器或者服務器集羣上時。redis
分佈式緩存比其餘緩存存儲在獨立服務器上的場景有幾個優勢。sql
當緩存數據是分佈式的:數據庫
不一樣分佈式緩存的實現,它們的配置不一樣。這篇文章會講解怎樣配置 SQL Server分佈式緩存 和 Redis分佈式緩存 。第三方實現也是可用的,例如,NCache. 無論選擇那一種實現,應用和緩存都是使用 IDistributedCache接口交互。api
1. 要使用SQL Server分佈式緩存,須要引入 Microsoft.AspNetCore.App metapackage 或者 添加 Microsoft.Extensions.Caching.SqlServer 包的引用數組
2. 要使用Redis 分佈式緩存,須要引用 Microsoft.AspNetCore.App metapackage 而且添加 Microsoft.Extensions.Caching.StackExchangeRedis 包的引用。由於Redis包沒有包含在 Microsoft.AspNetCore.App 中,因此必須分開引用Redis包。緩存
IDistributedCache接口提供下列方法來操做分佈式緩存中的數據項:服務器
在Startup.ConfigureServices中註冊一個IDistributedCache的實現。Framework提供的實如今這個主題會作一些描述,包括:app
Distributed Memory Cache 是存儲在內存中的 , 它不是一個現實(actual)中的分佈式緩存。緩存數據是存儲在應用運行的服務器上的。async
分佈式內存緩存是一個有用的實現:
在開發和測試場景
當生產環境是在一個單獨的服務器,而且內存消耗不是一個問題時。實現分佈式內存緩存來簡化數據存儲。它容許在未來實現一個真正的分佈式緩存解決方案若是多個結點或者容錯成爲可能 。(Implementing the Distributed Memory Cache abstracts cached data storage. It allows for implementing a true distributed caching solution in the future if multiple nodes or fault tolerance become necessary.)
這個示例中,應用是運行在開發環境,在 Startup.ConfigureServices中 ,使用 Distributed Memory Cache :
services.AddDistributedMemoryCache();
分佈式SQL Server 緩存實現容許分佈式緩存使用SQL Server數據庫做爲一個存儲備份。要在SQL Server實例中建立一個SQL Server緩存項(cached item),你應該用sql-cache工具。這個工具用你提供的name和schema建立一個table.
在SQL Server中經過運行sql-cache create命令建立一個table. 提供SQL Server實例(Data Source),數據庫(Initial Catalog),schema(例如, dbo),和表名(例如,TestCache):
dotnet sql-cache create "Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=DistCache;Integrated Security=True;" dbo TestCache
成功後,顯示:
Table and index were created successfully.
經過sql-cache工具建立的表(table)有下列的schema:
注意:應用在操做緩存值時,應該使用IDistributedCache,而不是一個SqlServerCache.即便用接口的方式
這個示例應用實現了SqlServerCache,在非開發環境,在Startup.ConfigureServices:
services.AddDistributedSqlServerCache(options => { options.ConnectionString = _config["DistCache_ConnectionString"]; options.SchemaName = "dbo"; options.TableName = "TestCache"; });
Redis是一個開源的in-memory 數據存儲,它常常用做一個分佈式緩存。你能夠在本地使用Redis,而且你能夠配置Azure Redis Cache爲一個Azure-hosted ASP.NET Core應用。
一個應用配置緩存實現,使用一個RedisCache實例在一個非開發環境,在Startup.ConfigureServices:
services.AddStackExchangeRedisCache(options => { options.Configuration = "localhost"; options.InstanceName = "SampleInstance"; });
使用本地機器上的Redis時,須要下載Redis,而且運行redis-server 。
好了,上面的1,2,3是講解不一樣緩存在 Startup.ConfigureServices 中的配置,使添加到項目中。下面講下如何使用
要使用IDistributedCache接口,能夠從應用中的任意構造函數中,請求一個IDistributedCache實例.這個實例經過依賴注入提供。
當應用啓動時,IDistributedCache被注入到Startup.Configure中。使用IApplicationLifetime使當前時間被緩存。
public void Configure(IApplicationBuilder app, IHostingEnvironment env, IApplicationLifetime lifetime, IDistributedCache cache) { lifetime.ApplicationStarted.Register(() => { var currentTimeUTC = DateTime.UtcNow.ToString(); //當前時間 byte[] encodedCurrentTimeUTC = Encoding.UTF8.GetBytes(currentTimeUTC); var options = new DistributedCacheEntryOptions() .SetSlidingExpiration(TimeSpan.FromSeconds(20)); cache.Set("cachedTimeUTC", encodedCurrentTimeUTC, options); });
在這個示例應用中,會把 IDistributedCache注入到IndexModel中被Index page使用。
代碼以下:
public class IndexModel : PageModel { private readonly IDistributedCache _cache; public IndexModel(IDistributedCache cache) { _cache = cache; } public string CachedTimeUTC { get; set; } public async Task OnGetAsync() { CachedTimeUTC = "Cached Time Expired"; var encodedCachedTimeUTC = await _cache.GetAsync("cachedTimeUTC"); if (encodedCachedTimeUTC != null) { CachedTimeUTC = Encoding.UTF8.GetString(encodedCachedTimeUTC); } } public async Task<IActionResult> OnPostResetCachedTime() { var currentTimeUTC = DateTime.UtcNow.ToString(); byte[] encodedCurrentTimeUTC = Encoding.UTF8.GetBytes(currentTimeUTC); var options = new DistributedCacheEntryOptions() .SetSlidingExpiration(TimeSpan.FromSeconds(20)); await _cache.SetAsync("cachedTimeUTC", encodedCurrentTimeUTC, options); return RedirectToPage(); } }
注意:對於IDistributedCache實例,沒有必要使用單例(Singleton)或者Scoped lifetime。(至少對於內置的實現沒有必要)
當考慮使用IDistributedCache的哪種實現對於你的應用最合適時,能夠考慮下:
Existing infrastructure 已存在的基礎設施
Performance requirements 表現(性能)要求
Cost 花銷
Team experience 團隊經驗
緩存解決方案一般依賴in-memory storage(內存存儲)來提供對緩存數據的快速檢索。可是內存是一個有限的資源,而且很難擴展(costly to expand;costly,昂貴的)。僅將經常使用數據存儲在緩存中。
一般來講,一個Redis cache比一個SQL Server cache 能提供更高的吞吐量(throughput:生產量,生產能力,吞吐量),而且更低的潛伏因素(latency:潛伏,潛伏因素). 然而,你們一般使用 benchmarking來判斷the performance characteristics of caching strategies(緩存策略的表現性能)。
當SQL Server被用做一個分佈式緩存備份存儲。使用同一個數據庫來緩存和普通數據的存儲,和檢索,會消極的影響二者的表現。咱們建議爲分佈式緩存備份存儲使用一個專用的SQL Server實例。
參考資料:
https://docs.microsoft.com/en-us/aspnet/core/performance/caching/distributed?view=aspnetcore-2.2