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

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

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

 
 

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(1, 0, 0),  

            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.Cache,4.0 之后重新进行了设计,提供一个
OutputCacheProvider 供开发人员扩展。默认情况,还是使用 System.Web.Caching.Cache。

 
 

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

自己搜索。

 
 

参考:

  1. http://www.cnblogs.com/knowledgesea/p/3904929.html
    asp.net缓存
    - 张龙豪
  2. 《ASP.NET 本质论》郝冠军

6. 缓存 - 《APS.NET本质论》的更多相关文章

  1. 1.网站应用程序 - 《APS.NET本质论》

    1.1.HTTP协议 浏览器与WEB服务器的协议是应用层协议,当前遵循HTTP/1.1,HTTP协议是无状态的协议 客户机与服务器通过请求和响应完成一次会话(Session),每次会话中,双方发送的数 ...

  2. MVC -18.缓存(2)

    一.MVC缓存简介 缓存是将信息(数据或页面)放在内存中以避免频繁的数据库存储或执行整个页面的生命周期,直到缓存的信息过期或依赖变更才再次从数据库中读取数据或重新执行页面的生命周期.在系统优化过程中, ...

  3. c#实例化继承类,必须对被继承类的程序集做引用 .net core Redis分布式缓存客户端实现逻辑分析及示例demo 数据库笔记之索引和事务 centos 7下安装python 3.6笔记 你大波哥~ C#开源框架(转载) JSON C# Class Generator ---由json字符串生成C#实体类的工具

    c#实例化继承类,必须对被继承类的程序集做引用   0x00 问题 类型“Model.NewModel”在未被引用的程序集中定义.必须添加对程序集“Model, Version=1.0.0.0, Cu ...

  4. .Net Core 跨平台开发实战-服务器缓存:本地缓存、分布式缓存、自定义缓存

    .Net Core 跨平台开发实战-服务器缓存:本地缓存.分布式缓存.自定义缓存 1.概述 系统性能优化的第一步就是使用缓存!什么是缓存?缓存是一种效果,就是把数据结果存在某个介质中,下次直接重用.根 ...

  5. 探究javascript对象和数组的异同,及函数变量缓存技巧

    javascript中最经典也最受非议的一句话就是:javascript中一切皆是对象.这篇重点要提到的,就是任何jser都不陌生的Object和Array. 有段时间曾经很诧异,到底两种数据类型用来 ...

  6. 哪种缓存效果高?开源一个简单的缓存组件j2cache

    背景 现在的web系统已经越来越多的应用缓存技术,而且缓存技术确实是能实足的增强系统性能的.我在项目中也开始接触一些缓存的需求. 开始简单的就用jvm(java托管内存)来做缓存,这样对于单个应用服务 ...

  7. ASP.NET Core 中间件之压缩、缓存

    前言 今天给大家介绍一下在 ASP.NET Core 日常开发中用的比较多的两个中间件,它们都是出自于微软的 ASP.NET 团队,他们分别是 Microsoft.AspNetCore.Respons ...

  8. ASP.NET Core 折腾笔记二:自己写个完整的Cache缓存类来支持.NET Core

    背景: 1:.NET Core 已经没System.Web,也木有了HttpRuntime.Cache,因此,该空间下Cache也木有了. 2:.NET Core 有新的Memory Cache提供, ...

  9. [Java 缓存] Java Cache之 DCache的简单应用.

    前言 上次总结了下本地缓存Guava Cache的简单应用, 这次来继续说下项目中使用的DCache的简单使用. 这里分为几部分进行总结, 1)DCache介绍; 2)DCache配置及使用; 3)使 ...

随机推荐

  1. java 方法的返回类型

    定义了返回值类型后 必须要执行 return 因为 当一个变量初始化时候 需要有数据 如果方法体里面没有返回数据类型时 这个变量是没有数据的 会报错 所以必须要返回一个数据 当一个方法体里面有 if ...

  2. DBA 这个角色

    下面这些领域的技能可以提升DBA团队对公司业务产生正面影响的重要能力: ---------------------------------------------------------------- ...

  3. 常用的sublime text 3插件(很爽哦)

    个人比较懒,平时喜欢用webstorm,但是因为webstorm打开实在太慢了,并且太看设备,所以本人编辑简单的文件依然会选择使用sublime,虽然网上有很多关于此类插件的分享了,但是感觉都是片段, ...

  4. 【刷题】LOJ 2587 「APIO2018」铁人两项

    题目描述 比特镇的路网由 \(m\) 条双向道路连接的 \(n\) 个交叉路口组成. 最近,比特镇获得了一场铁人两项锦标赛的主办权.这场比赛共有两段赛程:选手先完成一段长跑赛程,然后骑自行车完成第二段 ...

  5. 各种蕴含算法思想的DP - 2

    study from: https://www.cnblogs.com/flashhu/p/9480669.html 3.斜率dp study from:http://www.cnblogs.com/ ...

  6. Openstack运维指南文档整理

    非常全面的运维指南整理http://zjzone.cc/index.php/2017/07/31/openstack-yun-wei-wen-dang-zheng-li/

  7. python教程1:Python基础之数据类型和变量、字符串和编码

    视频链接:http://www.bilibili.com/video/av10730372/ 我是在Linux下玩python的,Linux下默认安装python,直接打个pyhon3就好了,pyth ...

  8. [应用篇]第六篇 JSTL之自定义函数标签库

      在之前的JSTL的总结中已经对函数标签库进行了一些说明,在这里我再一次重新整理一下! 自带函数标签库介绍 引入该标签库的方法为: <%@ taglib prefix="fn&quo ...

  9. python---补充django中文报错(1),Django2.7使用sys.setdefaultencoding('utf-8'),以及使用reload(sys)原因

    SyntaxError at /blog/ news/story Non-ASCII character , but no encoding declared; see http://python.o ...

  10. PHP-PSR-[0-4]代码规范

    PHP-FIG 在说啥是PSR-[0-4]规范的之前,我觉得我们有必要说下它的发明者和规范者:PHP-FIG,它的网站是:www.php-fig.org.就是这个联盟组织发明和创造了PSR-[0-4] ...