• 6. 缓存


    CaChe是ASP.NET中唯一可以根据服务器使用情况,动态管理内存使用的状态管理方案。我们通过每个缓存数据的键值字符串来区分缓存的数据。

    简单案例来说。将数据从数据库/文件取出放在服务器内存中,后来的用户获取数据,不用查询数据而直接从内存中获取,提高了访问速度,减轻服务器的压力。——经常查询,不经常改动

    题外话,分布式缓存:MemcacheRedis等。(现在的大数据项目需要用到这些)

       

    1.1 缓存的原理

    缓存需要注意以下几点

       

    1. 缓存的空间是有限的。
    2. 缓存的内容可能会失效,原因:
    • 绝对过期。在特定的时间点后,缓存数据失效,例如天气预报。
    • 活动过期。在一个时间间隔之内,如果数据没有使用,那么,数据将过期。
    • 缓存依赖

      缓存数据依赖于某个对象,例如文件系统中的文件或者文件夹,数据库中的数据等,当被依赖的对象发生变化,缓存的数据将成为脏数据。

    • 优先级。当缓存空间不够的时候,其他条件相同的情况下,通过优先级判断哪些数据需要从缓存中跑起掉。
    1. 通过移除通知,当缓存的数据被从缓存中移除的时候,可以通知应用程序。应用程序需要写一个符合特定委托的方法,以便接收通知。
    2. 由于内存有限,所以不太可能将所有数据缓存到内存中,因此,Cache 必须对缓存的数据进行有效的调度,以达到内存使用效率的最大化。

       

    1.2 .NET 中缓存管理实现

    在.NET中缓存的定义命名空间是 System.Web.Cachine

       

    1. Dependency 依赖:
    • .NET 中支持两种依赖:CacheDependency 和 SqlDependency。从.NET 2.0 开始,CacheDependency 不再密封,而是可以继承。

      CacheDependency :表示对文件或目录的依赖。

      SqlDependency :表示对 SQL 数据库的依赖。
       

    • 过期时间:过期时间分为绝对过期时间和滑动过期时间。(只能二选一)
      绝对过期时间为一个特定的时间点,类型是
      DateTime,如果不使用绝对过期时间,那么,使用 System.Web.Caching.Cache.
      • 绝对过期时间为一个特定的时间点,类型是 DateTime,如果不使用绝对过期时间,那么,使用 System.Web.Caching.Cache.NoAbsoluteExpiration 表示。
      • 滑动过期时间为一个时间间隔,类型为 TimeSpan,如果不使用滑动过期时间,使用 System.Web.Cachine.NoSlidingExpiration 表示。
         
    1. 优先级 CacheItemPrority

      由于我们需要缓存大量的数据,在内存有限的情况下,就必须对缓存的数据进行优先级分类,重要的数据可以更长时间保存在内存中。CacheItemPriority 是一个枚举类型,从高到低定义了如下优先级:

    • NotRemoveable,最高优先级,不会因为内存调整被移除,除非过期或者缓存依赖被清除。
    • High,服务器释放内存时,最不可能被移除
    • AboveNormal,被移除的可能性比 Normal 小
    • Normal,具有该级别的数据很可能被移除。
    • Default,就是 Normal 级别
    • BelowNormal,具有该优先级的数据比 Normal 级别更有可能移除。
    • Low,此级别的数据最可能被移除。
       
    1. 删除通知:

      .NET 提供了一个机制,当被缓存的数据从内存中移除的时候,可以提供一个通知机制,来回调用户定义的方法,方法必须符合 CacheItemRemovedCallback 委托的定义。
       

      public delegate void CacheItemRemovedCallback {  

        string key,  

        Object value,  

        CacheItemRemovedReason reason  

      }  


      其中,
      CacheItemRemovedReason 未婚村被移除的原因。CacheItemRemovedReason 是一个枚举类型,
      定义了如下原因:

      DependencyChanged,由于依赖发生变化被移除。

      Expired,由于过期被移除。

      Removed,由于调用 Insert 插入一个同名的缓存项或者调用 Remove 失效被移除。

      Underused,系统移除。
       

    2. 特别注意:

      回调的时机是不可预测的,不能假定回调发生时,回调方法的执行线程存在 HttpContext 的上下文,为了在没有请求上下文的时候取得对 Cache 对象的引用,可以通过 HttpRuntime Cache 属性来使用应用程序的 Cache 。

    • 不能在页面上使用实例方法来作为回调方法,当在页面上使用回调方法时,由于指向回调方法的引用会阻止垃圾回收机制,因此会造成内存很快消耗光。
    • 一般通过在自定义类的静态方法实现回调方法,或使用页面对象的静态方法实现。

       

    1.3.基于文件的缓存依赖

     

    CacheDependency 表示依赖对于文件或者目录的依赖。

     

    Public class CacheDependency : Idisposable

       

    通过改变文件的更新日期来清除缓存。

       

    public static string Message  

    {  

    get {

        HttpContext context = System.Web.HttpContext.Current;  

        

        string message = context.Cache["Message"] as string;  

        

        if (message == null)  

        {  

            string path = context.Server.MapPath("~/TextFile.txt");  

            message = System.IO.File.ReadAllText(path);  

        

            context.Cache.Add(  

                "Message",  

                message,  

                new CacheDependency(path),  

                Cache.NoAbsoluteExpiration,  

                new TimeSpan(100),  

                CacheItemPriority.Normal,  

                CallBack  

                );  

        }  

        return message;  

    }  

    }

        

    /// <param name="reason">原因</param>  

    private static void CallBack(string key, Object value, CacheItemRemovedReason reason)  

    {  

        //但是需要注意的是,此时不一定有请求  

        //因此,不能使用 HttpContext  

        

        //如果需要使用 Cache  

        //可以通过 System.Web.HttpRuntime.Cache 来获取当前网站应用程序的 Cache  

    }  

       

    Cache.Insert Cache.Add 区别 

       

    1.4 基于 SQL 的缓存依赖

    当数据库信息变化时,应用程序获取变化的通知是缓存依赖得以实现的基础。

    • 数据库通知:

      当数据库中信息变化,主动通知应用程序。

    • 轮询:

      数据库不能通知的时候,应用程序主动定期访问数据库,检查数据变化。

    微软从 SQL Server 2005开始提供数据库通知。如果数据库不支持通知机制,那么只能通过轮询来实现。

    但是轮询不可能再次查询一遍进行比较,我们通常通过触发器来实现。

       

    轮询的方法:

    sqlCacheDependency 的 enabled 属性为真,表示启动轮询,pollTime,毫秒为单位,意识是每隔2秒检测下数据库,检测表是否有发生变化。connectionStringName为数据库链接字符串。

       

    <connectionStrings>       

        <add name="Am_WeixinWeb" connectionString="data source=192.168.1.200;initial catalog=Am_WeixinWeb;uid=sa;password=lh1234;"  />  

      </connectionStrings>  

       

    <system.web>  

      <caching>  

        <sqlCacheDependency enabled="true" pollTime="2000">  

          <databases>  

            <add name="Test" connectionStringName="Am_WeixinWeb" />  

          </databases>  

        </sqlCacheDependency>  

      </caching>  

       

    SqlCacheDependency 表示 SQL 缓存依赖对象,即支持通知机制也可以支持轮询机制。

    创建 SqlCacheDependency 对象的方法如下:

       

    SqlCacheDependency dep = new SqlCacheDependency("Test""Am_recProScheme");  //Test对应配置项的缓存配置key ,后面是数据库表名  

       

    如果使用 SQL 2005 以及后面的版本,可以使用通知机制。

       

    Alter database 数据库名称 set enable_broker  

       

    然后,定义一个有效的查询对象来获取数据库的查询通知。SqlCommand 必须满足如下要求:

    表名必须包括所有者名称的完全限定名;

    Select 显式指定列名,不能使用 * 来选择所有列。

       

    SqlCommand command = new SqlCommand(connectionString,sql);  

       

    最后,构造 SQL 缓存依赖对象,

       

    SqlCacheDependency scd = new SqlCacheDependency (command);  

       

    如果使用通知机制,不需要使用工具在数据库中做准备工作,也不需要在配置文件中设置轮询。

       

    1.5 组合的缓存依赖

    当依赖的内容为多个 Denpendency (可能是 CacheDependency 或者 SqlDependency)时,可以通过 AggregateCacheDependency 创建依赖的组合,在任何一个依赖项变化时,使缓存失效。

       

    1.6 删除所有缓存项目

    Cache 中没有内建清除全部项目的方法。所以必须遍历这个集合,去的其中的 Key 的集合,然后再遍历所有的 Key ,使用 Key 删除缓存项目。

       

    1.7 Web 服务器端的页面缓存

       

    1.8 页面局部缓存

    页面部分缓存是将页面部分内容保存在内存中以便响应用户请求。两种:

    1.用户控件缓存

    在用户控件中的 OutputCache 指令支持选项:

    • Duration
    • VaryByParam
    • VaryByControl
    • VaryByCustom
    • VaryByContentEncodings
    • Shared
    • SqlDenpendcy

       

    2.缓存后替换

    大部分内容需要缓存,某些片断内容是动态的。

    例如新闻页面,新闻内容大部分时间不变,但是页面显示的当前时间、广告信息等需要随时变化。

    缓存后替换:将整个页面输出缓存,将特定部分标记为不缓存。

    三种方式:

    • 声明的方式使用 Substitution 控件
    • 编程的方式使用 Substitution 控件
    • 使用 Adrotor 控件

       

    * 1.9 自定义的输出缓存提供器

    .NET 4.0 之前使用 System.Web.Caching.Cache4.0 之后重新进行了设计,提供一个 OutputCacheProvider 供开发人员扩展。默认情况,还是使用 System.Web.Caching.Cache

       

    题外:2.1 Memcached 分布式内存对象缓存系统

    自己搜索。

       

    参考:

    1. http://www.cnblogs.com/knowledgesea/p/3904929.html asp.net缓存 - 张龙豪
    2. ASP.NET 本质论》郝冠军
  • 相关阅读:
    confluence --常用插件整合
    fuse--s3挂载到centos7.5服务器
    gvm--go版本管理工具
    等保1.0与等保2.0的区别
    postfix -- 发件调试
    postfix邮件服务器
    confluence -- 命令行备份还原
    浏览器使用小tip
    windows如何正确下载补丁包
    xwiki使用中的问题
  • 原文地址:https://www.cnblogs.com/tangge/p/6557384.html
Copyright © 2020-2023  润新知