asp.net core 系列之Response caching 之 Distributed caching(3)
这篇文章讲解分布式缓存,即 Distributed caching in ASP.NET Core
Distributed caching in ASP.NET Core
分布式缓存是可以在多个应用服务上共享的缓存,比较经典的用法是作为多个应用服务器的一个可到达的外部服务。分布式缓存可以提高 ASP.NET Core应用的性能和扩展性(performance and scalability), 特别是当应用是部署在云服务器或者服务器集群上时。
分布式缓存比其他缓存存储在独立服务器上的场景有几个优点。
当缓存数据是分布式的:
- 跨多个服务器的请求时,数据是一致的
- 比服务器重启和应用部署存在的时间长
- 不使用本地内存
不同分布式缓存的实现,它们的配置不同。这篇文章会讲解怎样配置 SQL Server分布式缓存 和 Redis分布式缓存 。第三方实现也是可用的,例如,NCache. 不管选择那一种实现,应用和缓存都是使用 IDistributedCache接口交互。
一.Prerequisites(先决条件)
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 interface
IDistributedCache接口提供下列方法来操作分布式缓存中的数据项:
- Get, GetAsync :接受string类型的key, 如果在缓存中找到了,缓存数据会以byte[]数组的形式输出
- Set, SetAsync :往缓存中添加缓存数据
- Refresh, RefreshAsync : 根据key值,刷新缓存中的数据项,重置它的过期时间
- Remove, RemoveAsync : 删除缓存的数据项
三. Establish distributed caching services (建立分布式服务)
在Startup.ConfigureServices中注册一个IDistributedCache的实现。Framework提供的实现在这个主题会做一些描述,包括:
- Distributed Memory Cache(分布式内存缓存)
- Distributed SQL Server cache(分布式SQL Server缓存)
- Distributed Redis cache(分布式Redis缓存)
1. Distributed Memory Cache
Distributed Memory Cache 是存储在内存中的 , 它不是一个现实(actual)中的分布式缓存。缓存数据是存储在应用运行的服务器上的。
分布式内存缓存是一个有用的实现:
在开发和测试场景
当生产环境是在一个单独的服务器,并且内存消耗不是一个问题时。实现分布式内存缓存来简化数据存储。它允许在将来实现一个真正的分布式缓存解决方案如果多个结点或者容错成为可能 。(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();
2. Distributed SQL Server Cache
分布式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";
});
3. Distributed Redis Cache
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 中的配置,使添加到项目中。下面讲下如何使用
四.Use the distributed cache
要使用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());
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());
await _cache.SetAsync("cachedTimeUTC", encodedCurrentTimeUTC, options); return RedirectToPage();
}
}
注意:对于IDistributedCache实例,没有必要使用单例(Singleton)或者Scoped lifetime。(至少对于内置的实现没有必要)
五.Recommendations
当考虑使用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
asp.net core 系列之Response caching 之 Distributed caching(3)的更多相关文章
- asp.net core 系列之Response caching(1)
这篇文章简单的讲解了response caching: 讲解了cache-control,及对其中的头和值的作用,及设置来控制response caching; 简单的罗列了其他的缓存技术:In-me ...
- Ajax跨域问题及解决方案 asp.net core 系列之允许跨越访问(Enable Cross-Origin Requests:CORS) c#中的Cache缓存技术 C#中的Cookie C#串口扫描枪的简单实现 c#Socket服务器与客户端的开发(2)
Ajax跨域问题及解决方案 目录 复现Ajax跨域问题 Ajax跨域介绍 Ajax跨域解决方案 一. 在服务端添加响应头Access-Control-Allow-Origin 二. 使用JSONP ...
- asp.net core系列 38 WebAPI 返回类型与响应格式--必备
一.返回类型 ASP.NET Core 提供以下 Web API Action方法返回类型选项,以及说明每种返回类型的最佳适用情况: (1) 固定类型 (2) IActionResult (3) Ac ...
- asp.net core 系列 16 Web主机 IWebHostBuilder
一.概述 在asp.net core中,Host主机负责应用程序启动和生存期管理.host主机包括Web 主机(IWebHostBuilder)和通用主机(IHostBuilder).Web 主机是适 ...
- asp.net core 系列 14 错误处理
一.概述 本文介绍处理 ASP.NET Core 应用中常见错误的一些方法.主要是关于:开发环境异常页:非开发环境配置自定义异常处理页:配置状态代码页(没有正文响应,http状态400~599的). ...
- asp.net core 系列 8 Razor框架路由(下)
三.页面路由操作约定 接着上篇讲asp.net core 系列 7 Razor框架路由.在上篇继续第三节 "页面路由操作约定" 的最后一小节 AddPageRoute . 3.3. ...
- 技术的正宗与野路子 c#, AOP动态代理实现动态权限控制(一) 探索基于.NET下实现一句话木马之asmx篇 asp.net core 系列 9 环境(Development、Staging 、Production)
黄衫女子的武功似乎与周芷若乃是一路,飘忽灵动,变幻无方,但举手抬足之间却是正而不邪,如说周芷若形似鬼魅,那黄衫女子便是态拟神仙. 这段描写出自<倚天屠龙记>第三十八回. “九阴神抓”本是& ...
- 【asp.net core 系列】10 实战之ActionFilter
0.前言 在上一篇中,我们提到了如何创建一个UnitOfWork并通过ActionFilter设置启用.这一篇我们将简单介绍一下ActionFilter以及如何利用ActionFilter,顺便补齐一 ...
- 1.1专题介绍「深入浅出ASP.NET Core系列」
大家好,我是IT人张飞洪,专注于.NET平台十年有余. 工作之余喜欢阅读和写作,学习的内容包括数据结构/算法.网络技术.Linux系统原理.数据库技术原理,设计模式.前沿架构.微服务.容器技术等等…… ...
随机推荐
- nditer —— numpy.ndarray 多维数组的迭代
1. Single array iteration >>> a = np.arange(6).reshape(2,3) >>> for x in np.nditer ...
- 使用ant对项目进行多渠道打包时遇到问题记录
1.打包成功后,打开apk时,会出现闪退的现象解决方法:1.配置好ant后,先把项目正常运行后,再打包,如有问题见第2步 2.找到项目中build.xml,然后右键,选择Run As - ...
- RabbitMq核心概念和术语
简介 越来越多的消息中间件很容易让人产生混淆,在学习一种消息中间件的时候,最好先了解他的几种抽象概念,方便你理解,明白了这些概念,你学习起来的时候也就得心应手,同时也是使用好RabbitMQ的基础. ...
- 图灵机(Turing Machine)
图灵机,又称图灵计算.图灵计算机,是由数学家阿兰·麦席森·图灵(1912-1954)提出的一种抽象计算模型,即将人们使用纸笔进行数学运算的过程进行抽象,由一个虚拟的机器替代人们进行数学运算. 所谓的图 ...
- 基于Geoserver发布时间地图
Geoserver它是著名的开源GIS其中软件. 地图服务软件也经常使用的物品.基于geoserver和Openlayers它可以建立一个自由的,开放源码GIS工程. Geoserver公布地图的步骤 ...
- Python经常使用内置函数介绍【filter,map,reduce,apply,zip】
Python是一门非常简洁,非常优雅的语言,其非常多内置函数结合起来使用,能够使用非常少的代码来实现非常多复杂的功能,假设相同的功能要让C/C++/Java来实现的话,可能会头大,事实上Python是 ...
- 关于提高UDP发送效率的方法
UDP的发送效率和什么因素有关呢? 直观觉得,UDP的切包长越大,应该发送效率越高(最长为65536).可是依据实际測试和在网上查到的资料的结果,包长度为1024为发送效率最高. 这样的结果让人感到疑 ...
- Codeforces 15C Industrial Nim 简单的游戏
主题链接:点击打开链接 意甲冠军: 特定n 下列n行,每一行2的数量u v 表达v礧:u,u+1,u+2···u+v-1 问先手必胜还是后手必胜 思路: 首先依据Nim的博弈结论 把全部数都异或一下, ...
- EF codefirst第一篇
一直以来喜欢dbfirst 因为简单,一直不明白为什么codefirst会是主流,根据对ddd的学习终于知道了codefirst的目的 本文是对博客园 小崔的笔记本 文章 EF实体框架之CodeFi ...
- Entity States
Added. The entity does not yet exist in the database. The SaveChanges method must issue an INSERT st ...