zoukankan      html  css  js  c++  java
  • 第十二节:Asp.Net Core 之分布式缓存(SQLServer和Redis)

    一. 整体说明

    1. 说明

      分布式缓存通常是指在多个应用程序服务器的架构下,作为他们共享的外部服务共享缓存,常用的有SQLServer、Redis、NCache。

        特别说明一下:这里的分布式是指多个应用程序服务器,而不是指将Redis或SQLServer部署成分布式集群。

    2. 分布式缓存数据有以下几个特点

     A. 跨多个服务器请求

     B. 服务器重新启动和应用部署缓存仍然有效

     C. 不使用本地缓存

    本节主要介绍基于SQLServer和Redis的分布式缓存服务,在Asp.Net Core中,主要是基于IDistributedCache接口来实现分布式缓存服务。

    3.缓存方法介绍

    来自于IDistributedCache接口和DistributedCacheExtensions扩展类。

     A. 读取:Get、GetString及其对应的异步方法。根据key键获取对应的值,Get方法返回的byte数组,这里更常用GetString方法,返回字符串。

     B. 写入:Set、SetString及其对应的异步方法。同上,Set操控的是byte数组,这里更常用SetString方法。DistributedCacheEntryOptions,用于配置缓存的性质,下面详细介绍。

     C. 移除:Remove及其对应的异步方法。根据key键来移除缓存。

     D. 刷新重置:Refresh及其对应的异步方法。刷新缓存基于其密钥,重置其滑动到期超时值(如果有)中的项。

    4. 缓存性质介绍

    这里通过DistributedCacheEntryOptions类配置,通过F12观察代码可知,可以设置以下三个属性。

     A. DateTimeOffset? AbsoluteExpiration:绝对过期时间,如: new DateTimeOffset(DateTime.Parse("2019-07-16 16:33:10"));

     B. TimeSpan? AbsoluteExpirationRelativeToNow:绝对过期时间,如: TimeSpan.FromSeconds(10);

     C. TimeSpan? SlidingExpiration:相对过期时间,如: TimeSpan.FromSeconds(10);

     

    二. SqlServer分布式缓存

    1. 前提

      安装【Microsoft.Extensions.Caching.SqlServer】程序集,如果是Core MVC程序,自带的Microsoft.AspNetCore.App包里已经涵盖了该程序集,无需重复安装。

    2. 使用步骤

     A. 在数据库中新建一个名叫“CacheDB”表,然后以管理员身份cmd运行下面指令,会创建一张名叫“AspNetCoreCache”表,相应的缓存信息都存在于这张表中。

    【dotnet sql-cache create "Server=localhost;User=sa;Password=123456;Database=CacheDB" dbo AspNetCoreCache】成功后会提示:Table and index were created successfully.

    PS:补充表的结构和含义, 分别是键、值、到期时刻(有问题)、滑动过期时间、绝对过期时间。

     B. 在ConfigureService中通过AddDistributedSqlServerCache方法注册SqlServer缓存服务,可以通过SqlServerCacheOptions对象全局配置缓存的性质。

      (PS:也可以使用的时候通过DistributedCacheEntryOptions类配置)

     1 {
     2   "Logging": {
     3     "LogLevel": {
     4       "Default": "Warning"
     5     }
     6   },
     7   "AllowedHosts": "*",
     8   "SqlSeverConnectionString": "Server=localhost;User=sa;Password=123456;Database=CacheDB",
     9   //暂时没用到,使用Redis的时候,没有设置密码
    10   "RedisConnectionString": "172.16.1.250:6379,defaultDatabase=11,name=TestDb,password=Gworld2017,abortConnect=false"
    11 }
    1  //注册分布式的SQLServer缓存服务
    2  services.AddDistributedSqlServerCache(options =>
    3  {
    4      options.ConnectionString = Configuration["SqlSeverConnectionString"];
    5      options.SchemaName = "dbo";
    6      options.TableName = "AspNetCoreCache";
    7  });            

     C. 通过构造函数注入IDistributedCache对象

    1    public class ThirdController : Controller
    2     {
    3         public IDistributedCache _cache1 { get; set; }
    4 
    5         public ThirdController(IDistributedCache cache1)
    6         {
    7             _cache1 = cache1;
    8         }
    9     }

     D. 通过GetString和SetString进行读取和写入,通过DistributedCacheEntryOptions类配置。

     1   public IActionResult Index()
     2   {
     3 
     4      string nowTime = _cache1.GetString("t1");
     5       if (string.IsNullOrEmpty(nowTime))
     6       {
     7         nowTime = DateTime.Now.ToString();
     8 
     9         DistributedCacheEntryOptions options = new DistributedCacheEntryOptions();
    10         //1.相对过期时间
    11         //options.SlidingExpiration = TimeSpan.FromSeconds(10);
    12 
    13         //2. 绝对过期时间(两种形式)
    14         options.AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(100);
    15         //options.AbsoluteExpiration= new DateTimeOffset(DateTime.Parse("2019-07-16 16:33:10"));
    16 
    17         _cache1.SetString("t1", nowTime,options);
    18       }
    19      ViewBag.t1 = nowTime;
    20 
    21      return View();
    22  }

    4. 缓存性质的配置

    (1) 全局配置

     注册的时候通过SqlServerCacheOptions类配置,如下图,必须要配置的三个属性是:ConnectionString数据连接字符串、SchemaName表架构、Table表名称。

    (2) 使用时配置

     通过DistributedCacheEntryOptions类配置,上面已经介绍了。

    5. 扩展缓存清除相关问题

      在缓存过期后,每次调用 Get/GetAsync 方法都会 调用 SqlServerCache 的 私有方法 ScanForExpiredItemsIfRequired() 进行一次扫描, 然后清除所有过期的缓存条目,扫描方法执行过程也很简单,就是直接执行数据库查询语句  DELETE FROM {0} WHERE @UtcNow > ExpiresAtTime .

    特别注意:异步方法中同步调用会导致过期的缓存清除不了,所以使用异步的话就异步到底。 await this.cache.GetStringAsync("CurrentTime");

    三. Redis分布式缓存

    1. 前提

      安装【Microsoft.Extensions.Caching.StackExchangeRedis】程序集,Core MVC中这个也是不包含的。

    2. 使用步骤

     A. 下载Redis程序,打开redis-server.exe,启动Redis。

     B. 在ConfigureService中通过AddStackExchangeRedisCache方法注册Redis缓存服务。 必须要设置的是Configuration连接字符串和InstanceName实例名。

    1    //注册分布式的Redis缓存服务
    2     services.AddStackExchangeRedisCache(options =>
    3     {
    4           options.Configuration = "localhost";
    5           options.InstanceName = "SampleInstance";
    6      });

     C. 通过构造函数注入IDistributedCache对象。

     D. 通过GetString和SetString进行读取和写入,通过DistributedCacheEntryOptions类配置。

    C D 两步代码和上述SqlServer的完全相同。

     1   public class ThirdController : Controller
     2     {
     3         public IDistributedCache _cache1 { get; set; }
     4 
     5         public ThirdController(IDistributedCache cache1)
     6         {
     7             _cache1 = cache1;
     8         }
     9 
    10         public IActionResult Index()
    11         {
    12 
    13             string nowTime = _cache1.GetString("t1");
    14             if (string.IsNullOrEmpty(nowTime))
    15             {
    16                 nowTime = DateTime.Now.ToString();
    17 
    18                 DistributedCacheEntryOptions options = new DistributedCacheEntryOptions();
    19                 //1.相对过期时间
    20                 //options.SlidingExpiration = TimeSpan.FromSeconds(10);
    21 
    22                 //2. 绝对过期时间(两种形式)
    23                 options.AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(100);
    24                 //options.AbsoluteExpiration= new DateTimeOffset(DateTime.Parse("2019-07-16 16:33:10"));
    25 
    26                 _cache1.SetString("t1", nowTime,options);
    27             }
    28             ViewBag.t1 = nowTime;
    29 
    30             return View();
    31         }
    32     }

    3. 缓存方法和缓存性质

      同SqlServer中相同的完全相同

    4. 缓存清除与SqlServer的区别

      使用 Redis 分布式缓存允许你在异步方法中调用同步获取缓存的方法,这不会导致缓存清理的问题,因为缓存的管理已经完全交给了 Redis 客户端 StackExchange.Redis了

    5. 总结

      细心的你可能已经发现了,上面的这段代码和之前演示的 SqlServerCache 完全一致,是的,仅仅是修改一下ConfigureService注册的方法,我们就能在项目中进行无缝的切换;但是,对于缓存有强依赖的业务,建议还是需要做好缓存迁移,确保项目能够平滑过渡。

     

    !

    • 作       者 : Yaopengfei(姚鹏飞)
    • 博客地址 : http://www.cnblogs.com/yaopengfei/
    • 声     明1 : 本人才疏学浅,用郭德纲的话说“我是一个小学生”,如有错误,欢迎讨论,请勿谩骂^_^。
    • 声     明2 : 原创博客请在转载时保留原文链接或在文章开头加上本人博客地址,否则保留追究法律责任的权利。
     
  • 相关阅读:
    C++实现希尔排序和快排
    操作系统重点知识汇总
    结构体(对齐规则及举例)
    指针和引用(传指针和传引用)
    数组和指针
    判断一个字符是否为数字的两种方法(C/C++)
    浅谈操作系统栈和堆(区别与联系)
    浅谈malloc/free和new/delete 的区别
    操作符和表达式
    windows重装系统后grub引导菜单修复方法(亲自实验过)
  • 原文地址:https://www.cnblogs.com/yaopengfei/p/11121984.html
Copyright © 2011-2022 走看看