6. 缓存 - 《APS.NET本质论》
CaChe是ASP.NET中唯一可以根据服务器使用情况,动态管理内存使用的状态管理方案。我们通过每个缓存数据的键值字符串来区分缓存的数据。
简单案例来说。将数据从数据库/文件取出放在服务器内存中,后来的用户获取数据,不用查询数据而直接从内存中获取,提高了访问速度,减轻服务器的压力。——经常查询,不经常改动。
题外话,分布式缓存:Memcache,Redis等。(现在的大数据项目需要用到这些)
1.1 缓存的原理
缓存需要注意以下几点
- 缓存的空间是有限的。
- 缓存的内容可能会失效,原因:
- 绝对过期。在特定的时间点后,缓存数据失效,例如天气预报。
- 活动过期。在一个时间间隔之内,如果数据没有使用,那么,数据将过期。
- 缓存依赖。
缓存数据依赖于某个对象,例如文件系统中的文件或者文件夹,数据库中的数据等,当被依赖的对象发生变化,缓存的数据将成为脏数据。
- 优先级。当缓存空间不够的时候,其他条件相同的情况下,通过优先级判断哪些数据需要从缓存中跑起掉。
- 通过移除通知,当缓存的数据被从缓存中移除的时候,可以通知应用程序。应用程序需要写一个符合特定委托的方法,以便接收通知。
- 由于内存有限,所以不太可能将所有数据缓存到内存中,因此,Cache 必须对缓存的数据进行有效的调度,以达到内存使用效率的最大化。
1.2 .NET 中缓存管理实现
在.NET中缓存的定义命名空间是 System.Web.Cachine
中
- 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 表示。
- 优先级 CacheItemPrority:
由于我们需要缓存大量的数据,在内存有限的情况下,就必须对缓存的数据进行优先级分类,重要的数据可以更长时间保存在内存中。CacheItemPriority 是一个枚举类型,从高到低定义了如下优先级:
- NotRemoveable,最高优先级,不会因为内存调整被移除,除非过期或者缓存依赖被清除。
- High,服务器释放内存时,最不可能被移除
- AboveNormal,被移除的可能性比 Normal 小
- Normal,具有该级别的数据很可能被移除。
- Default,就是 Normal 级别
- BelowNormal,具有该优先级的数据比 Normal 级别更有可能移除。
- Low,此级别的数据最可能被移除。
- 删除通知:
.NET 提供了一个机制,当被缓存的数据从内存中移除的时候,可以提供一个通知机制,来回调用户定义的方法,方法必须符合
CacheItemRemovedCallback 委托的定义。
public delegate void CacheItemRemovedCallback {
string key,
Object value,
CacheItemRemovedReason reason
}
其中, CacheItemRemovedReason 未婚村被移除的原因。CacheItemRemovedReason 是一个枚举类型,
定义了如下原因:DependencyChanged,由于依赖发生变化被移除。
Expired,由于过期被移除。
Removed,由于调用 Insert 插入一个同名的缓存项或者调用 Remove 失效被移除。
Underused,系统移除。
- 特别注意:
回调的时机是不可预测的,不能假定回调发生时,回调方法的执行线程存在 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
}
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 分布式内存对象缓存系统
自己搜索。
参考:
- http://www.cnblogs.com/knowledgesea/p/3904929.html
asp.net缓存
- 张龙豪 - 《ASP.NET 本质论》郝冠军
6. 缓存 - 《APS.NET本质论》的更多相关文章
- 1.网站应用程序 - 《APS.NET本质论》
1.1.HTTP协议 浏览器与WEB服务器的协议是应用层协议,当前遵循HTTP/1.1,HTTP协议是无状态的协议 客户机与服务器通过请求和响应完成一次会话(Session),每次会话中,双方发送的数 ...
- MVC -18.缓存(2)
一.MVC缓存简介 缓存是将信息(数据或页面)放在内存中以避免频繁的数据库存储或执行整个页面的生命周期,直到缓存的信息过期或依赖变更才再次从数据库中读取数据或重新执行页面的生命周期.在系统优化过程中, ...
- 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 ...
- .Net Core 跨平台开发实战-服务器缓存:本地缓存、分布式缓存、自定义缓存
.Net Core 跨平台开发实战-服务器缓存:本地缓存.分布式缓存.自定义缓存 1.概述 系统性能优化的第一步就是使用缓存!什么是缓存?缓存是一种效果,就是把数据结果存在某个介质中,下次直接重用.根 ...
- 探究javascript对象和数组的异同,及函数变量缓存技巧
javascript中最经典也最受非议的一句话就是:javascript中一切皆是对象.这篇重点要提到的,就是任何jser都不陌生的Object和Array. 有段时间曾经很诧异,到底两种数据类型用来 ...
- 哪种缓存效果高?开源一个简单的缓存组件j2cache
背景 现在的web系统已经越来越多的应用缓存技术,而且缓存技术确实是能实足的增强系统性能的.我在项目中也开始接触一些缓存的需求. 开始简单的就用jvm(java托管内存)来做缓存,这样对于单个应用服务 ...
- ASP.NET Core 中间件之压缩、缓存
前言 今天给大家介绍一下在 ASP.NET Core 日常开发中用的比较多的两个中间件,它们都是出自于微软的 ASP.NET 团队,他们分别是 Microsoft.AspNetCore.Respons ...
- ASP.NET Core 折腾笔记二:自己写个完整的Cache缓存类来支持.NET Core
背景: 1:.NET Core 已经没System.Web,也木有了HttpRuntime.Cache,因此,该空间下Cache也木有了. 2:.NET Core 有新的Memory Cache提供, ...
- [Java 缓存] Java Cache之 DCache的简单应用.
前言 上次总结了下本地缓存Guava Cache的简单应用, 这次来继续说下项目中使用的DCache的简单使用. 这里分为几部分进行总结, 1)DCache介绍; 2)DCache配置及使用; 3)使 ...
随机推荐
- BZOJ 3174 拯救小矮人(贪心+DP)
题意 一群小矮人掉进了一个很深的陷阱里,由于太矮爬不上来,于是他们决定搭一个人梯.即:一个小矮人站在另一小矮人的 肩膀上,知道最顶端的小矮人伸直胳膊可以碰到陷阱口.对于每一个小矮人,我们知道他从脚到肩 ...
- Tyvj1038 忠诚 (线段树)
[Tyvj1038]忠诚 线段树 题目描述 老管家是一个聪明能干的人.他为财主工作了整整10年,财主为了让自已账目更加清楚.要求管家每天记k次账,由于管家聪明能干,因而管家总是让财主十分满意.但是 ...
- MT【173】齐次消元单变量
已知$x\ge0,x^2+(y-2)^2=1,W=\dfrac{3x^2+2\sqrt{3}xy+5y^2}{x^2+y^2}$,求$W$的最值. 提示:$x\ne0$时,设$t=\dfrac{y}{ ...
- MT【107】立体几何中用阿波罗尼乌斯圆的一道题
分析:利用内外圆知识知道,B,C两点到 AD 的距离$\le4$. 利用体积公式$V=\frac{1}{3}S_{截面}|AD|\le2\sqrt{15}$
- 【Luogu4609】建筑师(第一类斯特林数,组合数学)
[Luogu4609]建筑师(组合数学) 题面 洛谷 题解 首先发现整个数组一定被最高值切成左右两半,因此除去最高值之后在左右分开考虑. 考虑一个暴力\(dp\) ,设\(f[i][j]\)表示用了\ ...
- 【CF949D】Curfew(贪心)
[CF949D]Curfew(贪心) 题面 CF 洛谷 破池姐姐翻译好强啊 题解 今天菊开讲这题,我大力猜想一波说肯定从中间有个分界线,他还说可能是假的 大力贪心就好了,从两边往中间考虑,只要这个房间 ...
- NO.1: 视C++为一个语言联邦
C++由4个部分组成: 1.C part of C++; 2.Object-Oriented C++; 3.Template C++; 4.STL 请记住:C++的高效编程视状况而变化,取决你使用C+ ...
- linux c 编程 ------ 获取时间,计算程序执行时间
#include <time.h> #include <stdio.h> #include <unistd.h> int main(int argc, char a ...
- php 访问错误日志
/usr/local/php/var/log/php-fpm.log」—————————
- sql语句解析顺序和执行顺序
sql语句执行顺序1.from子句组装来自不同数据源的数据2.where子句基于指定的条件对记录行进行筛选3.group by子句将数据划分为多个分组4.使用聚集函数进行计算5.使用having子句筛 ...