- 浏览: 65533 次
- 性别:
- 来自: 上海
文章分类
最新评论
-
sanrenxing_1:
GoEasy 实时推送支持IE6-IE11及大多数主流浏览器的 ...
推送服务浅析 -
答案在风中:
youjianbo_han_87 写道你这种按照key规则来进 ...
缓存与分页 -
youjianbo_han_87:
你这种按照key规则来进行缓存分页有太大的局限性了。换个业务需 ...
缓存与分页 -
答案在风中:
jay61439476 写道//设置默认超时 ftpClien ...
关于文件传输 -
jay61439476:
//设置默认超时 ftpClient.setDefaultTi ...
关于文件传输
概述
在ASP.NET应用程序构建过程中,为了提高应用程序的性能,缓存处理无疑是一个非常重要的环节。通常,我们将一些频繁被访问的数据,以及一些需要大量处理时间得出来的数据缓存在内存中,从而提高性能。例如,如果程序需要处理一张报表,这张报表的数据是关联的几张数据库表,并通过大量的计算得到的数据。我们知道表关联是比较耗时的,如果关联之后得出的数据再进行聚合排序等操作的话,那速度会更慢。因此,我们把查询的报表数据缓存起来,等下次用户再次请求时直接从内存中读取已经生成好的报表,这样对用户和程序无疑都是一件非常好的事情,用户减少了等待时间,程序减轻了压力。
那么,何乐而不为呢,既然能让大家都开心的事情我们就去做吧。为此,ASP.NET提供了两种缓存方案。第一种是页输出缓存,它保存页处理输出,并在用户再次请求该页时,重用所保存的输出,而不是再次处理该页。第二种是应用程序缓存,它允许缓存您生成的数据,比如自定义报表对象,DataSet,DataTable等。但是有个问题就是ASP.NET为我们提供的缓存方案只能应用在单服务器中,如果我们的应用程序有几台服务器做负载均衡,或者我们做分布式应用,那么,ASP.NET为我们提供的缓存解决方案发挥的作用就不大了,我们需要其他的解决方案,现在比较成熟的缓存框架有Memcached,此框架用于分布式系统中,适用于Java,ASP.NET,PHP,Ruby等语言环境构建的应用程序。
那么,下面就一一阐述以上提到的缓存方案。
2、页输出缓存
在页输出缓存中,ASP.NET为我们提供了两种解决方案,第一种是页面级输出缓存,第二种是片段缓存(用户控件缓存)。两种方案各有各的应用场景,我们来分别阐述。
2.1、页面级输出缓存
页面级输出缓存是比较简单的缓存形式,它是将响应请求而发送的HTML副本保存在内存中,当再有请求时直接将缓存的HTML输出给用户,直到缓存过期。这样,程序的性能会得到非常大的提升。
实现
具体的实现就非常简单了,只要页面顶部加一条OutputCache指令就可以了。
<%@ OutputCache Duration="10" VaryByParam="none" %>
它支持五个属性(Duration,VaryByParam,Location,VaryByCustom,VaryByHeader),有两个(Duration,VaryByParam)是必须的,我们也就研究这两个属性就可以了,也基本够我们日常使用。
lDuration:页面应该被缓存的时间,以秒为单位。必须是正整数。
lVaryByParam:Request中变量的名称,这些变量名应该产生单独的缓存条目。"none"表示没有变动。"*"可用于为每个不同的变量数组创建新的缓存条目。变量之间用";"进行分隔。
lLocation:指定应该对输出进行缓存的位置。如果要指定该参数,则必须是下列选项之一:Any、Client、Downstream、None、Server或ServerAndClient。
lVaryByHeader:基于指定的标头中的变动改变缓存条目。
lVaryByCustom:允许在global.asax中指定自定义变动(例如,"Browser")。
示例
<1>.在Visual Studio .NET新建一个web项目,并且新建一个.aspx页面
<2>.删除页面的上面的默认HTML代码
<3>.把下面的代码COPY到刚新建的那个页面中
<%@ OutputCache Duration="10" VaryByParam="none"%>
<html>
<head runat="server">
<title>页面输出缓存示例</title>
<script. type="text/C#" runat="server">
void Page_Load(object sender, EventArgs e)
{
this.lblTime.Text = "Time:" + DateTime.Now.ToString();
}
</script>
</head>
<body>
<strong>页面输出缓存示例</strong>
<hr />
<br />
<asp:Label ID="lblTime" runat="server"></asp:Label>
<br />
<hr />
<a href="opc.aspx?categoryid=test1">categoryid(test1)</a>
<br />
<a href="opc.aspx?categoryid=test2">categoryid(test1)</a>
</body>
</html>
<4>.在浏览器中浏览此页面,您会页面上面的Time会有10秒的缓存,每过10秒,Time会变化一次,这时就是Duration="10"属性在起作用,因为我设置了缓存时间为10秒。好的,我们已经测试了Duration="10"属性。
<5>.我们点击下面的categoryid(test1)和categoryid(test2)两个链接,发现Time是一样的,为什么呢?那是因为我们设置VaryByParam属性为none,我们之前解释过VaryByParam属性为none表示没有变动,意为保存一个缓存,适用于页面只有一个缓存的情况。那我们现在这样一个情况,有一个产品列表数据,其数据是根据产品的分类来决定显示哪些产品,所以我们这里的关键问题是为每个分类产品分别产生缓存。这时就需要用到VaryByParam属性了,它的用途我们已经知道了,现在我们把它的属性设置为categoryid,现在再试试分别点击两个链接,你就会看到两个链接的页面缓存不一样了。
实战友情提示:
l 切记,Duration 是用秒进行指定的。
l 在使用 VaryByParam时,一定要注意 Request 变量大小写的变化会导致额外的缓存。比如刚才示例中categoryid=test1和categoryid=Test1会产生两个缓存版本,这里应用时要注意。
2.2、片段缓存(用户控件缓存)
对于页面级输出缓存的整页缓存方案,片段缓存是把页面的某个部分进行缓存,缓存一些很多页面所共有的页面部分,这样更节约内存资源,节约服务器压力,更符合面向对象的特点(封装)。比如页面的页头和页尾,很多页面都是公用相同的页头和页尾。再比如菜单部分,很多页面也是公用的一个菜单。这样,我们就可以一处缓存,多处使用。 像这样类似的场景我们就可以用片段缓存来实现。
实现
片段缓存的使用语法和页面输出缓存基本一样,但其应用于用户控件(.ascx文件),而页面输出缓存是应用于页面(.aspx文件)。对于其属性,它支持页面级输出缓存(除了Location属性)所有属性。并且用户控件还支持VaryByControl属性,该属性将根据用户控件(通常为用户控件页面上的控件,比如dropdownlist)成员的值改变而改变该控件的缓存。如果指定了VaryByControl,可以省略VaryByParam。
在默认情况下,对每一个页面上面引用的每个用户控件都是单独缓存的。如果一个用户控件不随应用程序中的页面改变而改变,并且在所有的页面中使用相同的名称(ID相同),且使用了Shared="true"参数,那么所有引用该用户控件的缓存版本都是一样的。
示例
<1>. 借用页面级输出缓存建立的WEB项目,新建一个用户控件(.ascx文件)
<2>. 把以下代码COPY到刚才新建的.ascx的页面文件中
<%@ OutputCache Duration="10" VaryByControl="ddlcity" Shared="true" %>
<script. type="text/C#" runat="server">
protected void Page_Load(object sender, EventArgs e)
{
this.lblUCTime.Text = "usercontrol time:"+ DateTime.Now.ToString();
}
</script>
<asp:DropDownList ID="ddlcity" runat="server" AutoPostBack="True">
<asp:ListItem Value="1">北京</asp:ListItem>
<asp:ListItem Value="2">江苏</asp:ListItem>
<asp:ListItem Value="3">上海</asp:ListItem>
<asp:ListItem Value="3">南京</asp:ListItem>
</asp:DropDownList>
<br />
<hr />
<br />
<asp:Label ID="lblUCTime" runat="server"></asp:Label>
<br />
<3>. 新建一个.aspx页面,并删除页面文件中的HTML代码,把以下代码复制到页面文件中(注意顶部.cs文件引用别删除,有下划线的需要您替换)
<%@ Register Src="您的用户控件.ascx" TagName="ucc" TagPrefix="uc1" %>
<html >
<head runat="server">
<title>片段缓存示例</title>
<script. type="text/C#" runat="server">
protected void Page_Load(object sender, EventArgs e)
{
this.lblSelfTime.Text = "self time:" + DateTime.Now.ToString();
}
</script>
</head>
<body>
<form. id="form1" runat="server">
<strong>片段缓存示例</strong>
<br />
<hr />
<uc1:ucc ID="Ucc1" runat="server" />
<br />
<hr />
<asp:Label ID="lblSelfTime" runat="server"></asp:Label>
</form>
</body>
</html>
<4>. 再新建一个.aspx文件,并删除页面文件中的HTML代码,把以下代码复制到页面文件中(注意顶部.cs文件引用别删除,有下划线的需要您替换)
<%@ Register Src="您的用户控件.ascx" TagName="ucc" TagPrefix="uc1" %>
<html >
<head id="Head1" runat="server">
<title>片段缓存示例2</title>
<script. type="text/C#" runat="server">
protected void Page_Load(object sender, EventArgs e)
{
this.lblSelfTime.Text = "self 2 time:" + DateTime.Now.ToString();
}
</script>
</head>
<body>
<form. id="form1" runat="server">
<strong>片段缓存示例2</strong>
<br />
<hr />
<uc1:ucc ID="Ucc1" runat="server" />
<br />
<hr />
<asp:Label ID="lblSelfTime" runat="server"></asp:Label>
</form>
</body>
</html>
<5>. 在浏览器中浏览您刚才新建的两个.aspx页面,会发现两个页面的用户控件的缓存是一样的(usercontrol time 是同时变化的),当您选择城市列表时,会发现用户控件为每一个城市都缓存了一个版本。不同页面的每个城市的缓存版本一样。
如果需要每个页面缓存版本不一样,就不要设置Shared="true"参数。大家可以通过上面的示例自己测试测试。
实战友情提示:
l 如果想每个页面引用的用户控件的缓存版本一样,就必须设置Shared="true"参数,并且用户控件ID一样
3、应用程序缓存
页面级和用户控件级缓存的确是一种可以迅速而简便地提高站点性能的方法,但是在ASP.NET中,缓存的真正灵活性和强大功能是通过Cache (System.Web.Caching.Cache)对象提供的。使用 Cache对象,您可以存储任何可序列化的数据对象,基于一个或多个依赖项的组合来控制缓存条目到期的方式。这些依赖项可以包括自从项被缓存后经过的时间、自从项上次被访问后经过的时间、对文件和/或文件夹的更改以及对其他缓存项的更改,在略作处理后还可以包括对数据库中特定表的更改。
实现
Cache对象位于System.Web.Caching. Cache中,其提供了两种增加缓存的方法,Add()和Insert()方法,这两种方法都有多个重载,且两种方法唯一的区别就是Add()返回已缓存对象的引用,Insert()没有返回值。Cache对象还提供了删除缓存的Remove()方法。
具体的缓存实践我这里提供了简易封装后一个缓存工具类。可以直接用于项目中(适用于ASP.NET 2.0项目)。
using System;
using System.Text;
using System.Web.Caching;
using System.Collections;
using System.Collections.Generic;
using System.Text.RegularExpressions;
namespace DianPing001.Cache
{
public static class ObjectCache
{
private static System.Web.Caching.Cache cache;
private static double _SaveTime;
/// <summary>
/// 缓存保存时间,以分钟计算,默认分钟
/// </summary>
public static double SaveTime
{
get { return _SaveTime; }
set { _SaveTime = value; }
}
static ObjectCache()
{
cache = System.Web.HttpContext.Current.Cache;
_SaveTime = 30.0;
}
/// <summary>
/// 获取缓存对象
/// </summary>
/// <param name="key">key</param>
/// <returns>object</returns>
public static object Get(string key)
{
return cache.Get(key);
}
/// <summary>
/// 获取缓存数据,需要传入类型
/// </summary>
public static T Get<T>(string key)
{
object bj = Get(key);
if (obj == null)
{
return default(T);
}
else
{
return (T)obj;
}
}
/// <summary>
/// 插入对象到缓存中
/// </summary>
/// <param name="key">key</param>
/// <param name="value">对象</param>
/// <param name="dependency">对象依赖</param>
/// <param name="priority">优先级</param>
/// <param name="callback">缓存删除时的回调事件</param>
public static void Insert(string key, object value, CacheDependency dependency, CacheItemPriority priority, CacheItemRemovedCallback callback)
{
cache.Insert(key, value, dependency, System.Web.Caching.Cache.NoAbsoluteExpiration, TimeSpan.FromMinutes(SaveTime), priority, callback);
}
/// <summary>
/// 插入对象到缓存中
/// </summary>
/// <param name="key">key</param>
/// <param name="value">对象</param>
/// <param name="dependency">对象依赖</param>
/// <param name="callback">缓存删除时的回调事件</param>
public static void Insert(string key, object value, CacheDependency dependency, CacheItemRemovedCallback callback)
{
Insert(key, value, dependency, CacheItemPriority.Default, callback);
}
/// <summary>
/// 插入对象到缓存中
/// </summary>
/// <param name="key">key</param>
/// <param name="value">对象</param>
/// <param name="dependency">对象依赖</param>
public static void Insert(string key, object value, CacheDependency dependency)
{
Insert(key, value, dependency, CacheItemPriority.Default, null);
}
/// <summary>
/// 插入对象到缓存中
/// </summary>
/// <param name="key">key</param>
/// <param name="value">对象</param>
public static void Insert(string key, object value)
{
Insert(key, value, null, CacheItemPriority.Default, null);
}
/// <summary>
/// 获取所有缓存对象的key
/// </summary>
/// <returns>返回一个IList对象</returns>
public static IList<string> GetKeys()
{
List<string> keys = new List<string>();
IDictionaryEnumerator cacheItem = cache.GetEnumerator();
while (cacheItem.MoveNext())
{
keys.Add(cacheItem.Key.ToString());
}
return keys.AsReadOnly();
}
/// <summary>
/// 删除缓存对象
/// </summary>
/// <param name="key">key</param>
public static void Remove(string key)
{
cache.Remove(key);
}
/// <summary>
/// 删除全部缓存
/// </summary>
public static void RemoveAll()
{
IList<string> keys = GetKeys();
foreach (string key in keys)
{
cache.Remove(key);
}
}
public static IList<string> RegexSearch(string pattern)
{
List<string> keys = new List<string>();
IDictionaryEnumerator cacheItem = cache.GetEnumerator();
while (cacheItem.MoveNext())
{
if (Regex.IsMatch(cacheItem.Key.ToString(), pattern))
{
keys.Add(cacheItem.Key.ToString());
}
}
return keys.AsReadOnly();
}
/// <summary>
/// 删除符合正则条件的cache
/// </summary>
/// <param name="pattern">条件</param>
public static void RegexRemove(string pattern)
{
IList<string> keys = RegexSearch(pattern);
foreach (string key in keys)
{
cache.Remove(key);
}
}
}
}
具体的使用场景
l 添加缓存
/// <summary>
/// 获取全部友情链接
/// </summary>
/// <returns></returns>
public List<Links> GetAll()
{
List<Links> linksList = ObjectCache.Get<List<Links>>("c_Links_ALL");[stone1]
if (linksList == null)
{
linksList = ProviderManager.Factory.Links.GetAll();
ObjectCache.Insert("c_Links_ALL",linksList);
}
[stone2]return linksList;
}
l 删除缓存
/// <summary>
/// 删除友情链接
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public int Delete(int id)
{
int retVar = ProviderManager.Factory.Links.Delete(id);
if (retVar > 0)
{
ObjectCache.RegexRemove("c_Links*");[stone3]
}
return retVar;
}
到这里,已经介绍了ASP.NET为我们提供的缓存方案,从简单的页面级和用户控件缓存,到功能强大、可灵活定制的Cache对象。这些已经基本满足我们日常的需求。当然,缓存的强大之处还需要我们在实战中慢慢体会。
4、分布式缓存
在ASP.NET中已经为我们提供了一些缓存方案,但是如果我们需要搭建分布式缓存系统的话,ASP.NET提供的方案就不够用了。因此我们需要其他的解决方案。寻觅的一段时间后,发现一个叫Memcached的用于分布式系统的缓存方案。如果你想快速搭建性能卓越,功能强大的分布式系统,那Memcached绝对是您不二的选择。
1)Memcached是什么?
memcached 是以LiveJournal 旗下Danga Interactive 公司的Brad Fitzpatric 为首开发的一款软件。许多Web应用都将数据保存到RDBMS中,应用服务器从中读取数据并在浏览器中显示。但随着数据量的增大、访问的集中,就会出现RDBMS的负担加重、数据库响应恶化、网站显示延迟等重大影响。
这时就该memcached大显身手了。memcached是高性能的分布式内存缓存服务器。一般的使用目的是,通过缓存数据库查询结果,减少数据库访问次数,以提高动态Web应用的速度、提高可扩展性。
2)Memcached能缓存什么?
通过在内存里维护一个统一的巨大的hash表,Memcached能够用来存储各种格式的数据,包括图像、视频、文件以及数据库检索的结果等。
3)Memcached快吗?
非常快,必须要介绍它的内部实现原理,只要知道有哪些站点在应用就可以了。Memcached已经成为mixi、hatena、Facebook、Vox、LiveJournal等众多服务中提高Web应用扩展性的重要因素。所以我们应该有理由相信Memcached的性能。
4)Memcached特点
memcached作为高速运行的分布式缓存服务器,具有以下的特点。
• 协议简单
• 基于libevent的事件处理
• 内置内存存储方式
• memcached不互相通信的分布式
5)Windows下Memcached的安装使用
a)安装Memcached Server
u 下载memcached的windows稳定版,解压放某个盘下面,比如在d:\memcached
u 在CMD下输入 "d:\memcached\memcached.exe -d install" 安装.
u 再输入:"d:\memcached\memcached.exe -d start" 启动。
备注:以后memcached将作为windows的一个服务每次开机时自动启动。这样服务器端已经安装完毕了。有几台缓存机器就为这些机器分别安装Memcached服务。
安装常用设置:
-p <num> 监听的端口
-l <ip_addr> 连接的IP地址, 默认是本机
-d start 启动memcached服务
-d restart 重起memcached服务
-d stop|shutdown 关闭正在运行的memcached服务
-d install 安装memcached服务
-d uninstall 卸载memcached服务
-u <username> 以<username>的身份运行 (仅在以root运行的时候有效)
-m <num> 最大内存使用,单位MB。默认64MB
-M 内存耗尽时返回错误,而不是删除项
-c <num> 最大同时连接数,默认是1024
-f <factor> 块大小增长因子,默认是1.25
-n <bytes> 最小分配空间,key+value+flags默认是48
-h 显示帮助
b)使用Memcached的.NET客户端
u 下载Memcached的.NET客户端(C#)
u 在项目中引用Enyim.Caching.dll文件
u 添加配置文件,WEB项目为web.config,客服端软件项目为App.config,配置代码为
<configuration>
<configSections>
<sectionGroup name="enyim.com">
<section name="memcached" type="Enyim.Caching.Configuration.MemcachedClientSection, Enyim.Caching" />
</sectionGroup>
<section name="memcached" type="Enyim.Caching.Configuration.MemcachedClientSection, Enyim.Caching" />
</configSections>
<enyim.com>
<memcached>
<servers>
<!-- put your own server(s) here-->
<add address="127.0.0.1" port="11211" />
<add address="192.168.111.189" port="11212" />
</servers>
<socketPool minPoolSize="10" maxPoolSize="100" connectionTimeout="00:00:10" deadTimeout="00:02:00" />
</memcached>
</enyim.com>
<memcached keyTransformer="Enyim.Caching.TigerHashTransformer, Enyim.Caching">
<servers>
<add address="127.0.0.1" port="11211" />
<add address="192.168.111.189" port="11212" />
</servers>
<socketPool minPoolSize="2" maxPoolSize="100" connectionTimeout="00:00:10" deadTimeout="00:02:00" />
</memcached>
</configuration>
u 测试代码
using System;
using System.Collections.Generic;
using System.Text;
using Enyim.Caching;
using Enyim.Caching.Memcached;
using Enyim.Caching.Configuration;
using System.Net;
namespace TestMemcached1
{
class Program
{
static void Main(string[] args)
{
string flag = "1"; //输入TAG,为插入缓存,为读取缓存数据,为删除缓存数据
string key = "";
string value = "";
MemcachedClient mc = new MemcachedClient();
Console.WriteLine("请输入操作类型(1插入缓存,读取缓存数据,删除缓存数据)...");
while((flag = Console.ReadLine().Trim()) != "")
{
switch (flag)
{
case "1": {
Console.WriteLine("请输入要插入缓存的KEY:");
key = Console.ReadLine().Trim();
Console.WriteLine("请输入与KEY对应的值:");
value = Console.ReadLine().Trim();
if (mc.Store(StoreMode.Set, key, value))
{
Console.WriteLine("{0}的值({1})插入成功",key,value);
}
}; break;
case "2": {
Console.WriteLine("请输入要删除的缓存的KEY");
key = Console.ReadLine().Trim();
if (mc.Get(key) == null)
{
Console.WriteLine("SORRY,{0}的值不存在", key);
}
else
{
if (mc.Remove(key))
{
Console.WriteLine("删除缓存({0})成功", key);
}
else
{
Console.WriteLine("删除缓存({0})失败", key);
}
}
}; break;
case "0": {
Console.WriteLine("请输入要读取缓存数据的KEY");
key = Console.ReadLine().Trim();
if (mc.Get(key) == null)
{
Console.WriteLine("SORRY,{0}的值不存在", key);
}
else
{
Console.WriteLine("{0}的缓存数据为{1}",key,mc.Get(key));
}
}; break;
default: Console.WriteLine("谢谢使用"); break;
}
}
}
}
}
c)运行结果
我是配置了两台服务器,本机和局域网内的一台机器,从配置文件中也可以看出具体配置了几台机器。
其运行结果也是非常让人满意的,我在本机添加的缓存,在192.168.111.189那台机器上面可以查询到刚刚添加的缓存,同样在189机器添加的缓存,我本机同样可以查询,当然删除也是同步的。
d)查看Memcached运行情况
使用telnet IP 端口 然后使用stats命令查看Memcached运行情况
e)实战友情提示:
Memcached在修改服务端口时发现CMD下的修改命令并不起效果。后来发现在安装好的Memcached服务的启动项中并没有端口设置(默认值为11211),于是想到进注册表修改其服务启动参数。打开注册表,按照路径HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\memcached Server,找到其中的ImagePath项,其值为:"d:\memcached\memcached.exe" -d runservice,将值修改为:"d:\memcached\memcached.exe" -p 80080 -m 256 -d runservice。重启服务后你就会发现该服务的端口已经变为80080了,-m 256表示设置了256M内存。
5、小结
到此为止,我们已经阐述了ASP.NET中各种缓存方案,并分享了一些实战经验。
从最基本的页面级和用户控件级简单缓存,到高灵活性、高性能的Cache缓存对象,以及功能强大、性能卓越的分布式缓存系统Memcached,我们都已经有所了解、有所深入。那么在实践过程中,我们应该根据自己的实际需要去选择具体的缓存方案。比如单服务器中,我们可以选择Cached缓存对象实现缓存,一些长期不做修改的动态页面我们可以选择页面级缓存,多页面公用的菜单我们可以选择用户控件缓存。分布式系统我们就可以选择Memcached解决方案。
有了这么多的缓存方案,让我们构建高性能的应用程序吧!
--------------------------------------------------------------------------------
[stone1]从缓存中读取数据并复制给对象列表
[stone2]如果未能从缓存中获取到数据,就先从数据库中读取,然后把对象添加到缓存中
[stone3]批量删除缓存(key中含有c_Links的缓存)
转载地址:http://space.itpub.net/183242/viewspace-700850
在ASP.NET应用程序构建过程中,为了提高应用程序的性能,缓存处理无疑是一个非常重要的环节。通常,我们将一些频繁被访问的数据,以及一些需要大量处理时间得出来的数据缓存在内存中,从而提高性能。例如,如果程序需要处理一张报表,这张报表的数据是关联的几张数据库表,并通过大量的计算得到的数据。我们知道表关联是比较耗时的,如果关联之后得出的数据再进行聚合排序等操作的话,那速度会更慢。因此,我们把查询的报表数据缓存起来,等下次用户再次请求时直接从内存中读取已经生成好的报表,这样对用户和程序无疑都是一件非常好的事情,用户减少了等待时间,程序减轻了压力。
那么,何乐而不为呢,既然能让大家都开心的事情我们就去做吧。为此,ASP.NET提供了两种缓存方案。第一种是页输出缓存,它保存页处理输出,并在用户再次请求该页时,重用所保存的输出,而不是再次处理该页。第二种是应用程序缓存,它允许缓存您生成的数据,比如自定义报表对象,DataSet,DataTable等。但是有个问题就是ASP.NET为我们提供的缓存方案只能应用在单服务器中,如果我们的应用程序有几台服务器做负载均衡,或者我们做分布式应用,那么,ASP.NET为我们提供的缓存解决方案发挥的作用就不大了,我们需要其他的解决方案,现在比较成熟的缓存框架有Memcached,此框架用于分布式系统中,适用于Java,ASP.NET,PHP,Ruby等语言环境构建的应用程序。
那么,下面就一一阐述以上提到的缓存方案。
2、页输出缓存
在页输出缓存中,ASP.NET为我们提供了两种解决方案,第一种是页面级输出缓存,第二种是片段缓存(用户控件缓存)。两种方案各有各的应用场景,我们来分别阐述。
2.1、页面级输出缓存
页面级输出缓存是比较简单的缓存形式,它是将响应请求而发送的HTML副本保存在内存中,当再有请求时直接将缓存的HTML输出给用户,直到缓存过期。这样,程序的性能会得到非常大的提升。
实现
具体的实现就非常简单了,只要页面顶部加一条OutputCache指令就可以了。
<%@ OutputCache Duration="10" VaryByParam="none" %>
它支持五个属性(Duration,VaryByParam,Location,VaryByCustom,VaryByHeader),有两个(Duration,VaryByParam)是必须的,我们也就研究这两个属性就可以了,也基本够我们日常使用。
lDuration:页面应该被缓存的时间,以秒为单位。必须是正整数。
lVaryByParam:Request中变量的名称,这些变量名应该产生单独的缓存条目。"none"表示没有变动。"*"可用于为每个不同的变量数组创建新的缓存条目。变量之间用";"进行分隔。
lLocation:指定应该对输出进行缓存的位置。如果要指定该参数,则必须是下列选项之一:Any、Client、Downstream、None、Server或ServerAndClient。
lVaryByHeader:基于指定的标头中的变动改变缓存条目。
lVaryByCustom:允许在global.asax中指定自定义变动(例如,"Browser")。
示例
<1>.在Visual Studio .NET新建一个web项目,并且新建一个.aspx页面
<2>.删除页面的上面的默认HTML代码
<3>.把下面的代码COPY到刚新建的那个页面中
<%@ OutputCache Duration="10" VaryByParam="none"%>
<html>
<head runat="server">
<title>页面输出缓存示例</title>
<script. type="text/C#" runat="server">
void Page_Load(object sender, EventArgs e)
{
this.lblTime.Text = "Time:" + DateTime.Now.ToString();
}
</script>
</head>
<body>
<strong>页面输出缓存示例</strong>
<hr />
<br />
<asp:Label ID="lblTime" runat="server"></asp:Label>
<br />
<hr />
<a href="opc.aspx?categoryid=test1">categoryid(test1)</a>
<br />
<a href="opc.aspx?categoryid=test2">categoryid(test1)</a>
</body>
</html>
<4>.在浏览器中浏览此页面,您会页面上面的Time会有10秒的缓存,每过10秒,Time会变化一次,这时就是Duration="10"属性在起作用,因为我设置了缓存时间为10秒。好的,我们已经测试了Duration="10"属性。
<5>.我们点击下面的categoryid(test1)和categoryid(test2)两个链接,发现Time是一样的,为什么呢?那是因为我们设置VaryByParam属性为none,我们之前解释过VaryByParam属性为none表示没有变动,意为保存一个缓存,适用于页面只有一个缓存的情况。那我们现在这样一个情况,有一个产品列表数据,其数据是根据产品的分类来决定显示哪些产品,所以我们这里的关键问题是为每个分类产品分别产生缓存。这时就需要用到VaryByParam属性了,它的用途我们已经知道了,现在我们把它的属性设置为categoryid,现在再试试分别点击两个链接,你就会看到两个链接的页面缓存不一样了。
实战友情提示:
l 切记,Duration 是用秒进行指定的。
l 在使用 VaryByParam时,一定要注意 Request 变量大小写的变化会导致额外的缓存。比如刚才示例中categoryid=test1和categoryid=Test1会产生两个缓存版本,这里应用时要注意。
2.2、片段缓存(用户控件缓存)
对于页面级输出缓存的整页缓存方案,片段缓存是把页面的某个部分进行缓存,缓存一些很多页面所共有的页面部分,这样更节约内存资源,节约服务器压力,更符合面向对象的特点(封装)。比如页面的页头和页尾,很多页面都是公用相同的页头和页尾。再比如菜单部分,很多页面也是公用的一个菜单。这样,我们就可以一处缓存,多处使用。 像这样类似的场景我们就可以用片段缓存来实现。
实现
片段缓存的使用语法和页面输出缓存基本一样,但其应用于用户控件(.ascx文件),而页面输出缓存是应用于页面(.aspx文件)。对于其属性,它支持页面级输出缓存(除了Location属性)所有属性。并且用户控件还支持VaryByControl属性,该属性将根据用户控件(通常为用户控件页面上的控件,比如dropdownlist)成员的值改变而改变该控件的缓存。如果指定了VaryByControl,可以省略VaryByParam。
在默认情况下,对每一个页面上面引用的每个用户控件都是单独缓存的。如果一个用户控件不随应用程序中的页面改变而改变,并且在所有的页面中使用相同的名称(ID相同),且使用了Shared="true"参数,那么所有引用该用户控件的缓存版本都是一样的。
示例
<1>. 借用页面级输出缓存建立的WEB项目,新建一个用户控件(.ascx文件)
<2>. 把以下代码COPY到刚才新建的.ascx的页面文件中
<%@ OutputCache Duration="10" VaryByControl="ddlcity" Shared="true" %>
<script. type="text/C#" runat="server">
protected void Page_Load(object sender, EventArgs e)
{
this.lblUCTime.Text = "usercontrol time:"+ DateTime.Now.ToString();
}
</script>
<asp:DropDownList ID="ddlcity" runat="server" AutoPostBack="True">
<asp:ListItem Value="1">北京</asp:ListItem>
<asp:ListItem Value="2">江苏</asp:ListItem>
<asp:ListItem Value="3">上海</asp:ListItem>
<asp:ListItem Value="3">南京</asp:ListItem>
</asp:DropDownList>
<br />
<hr />
<br />
<asp:Label ID="lblUCTime" runat="server"></asp:Label>
<br />
<3>. 新建一个.aspx页面,并删除页面文件中的HTML代码,把以下代码复制到页面文件中(注意顶部.cs文件引用别删除,有下划线的需要您替换)
<%@ Register Src="您的用户控件.ascx" TagName="ucc" TagPrefix="uc1" %>
<html >
<head runat="server">
<title>片段缓存示例</title>
<script. type="text/C#" runat="server">
protected void Page_Load(object sender, EventArgs e)
{
this.lblSelfTime.Text = "self time:" + DateTime.Now.ToString();
}
</script>
</head>
<body>
<form. id="form1" runat="server">
<strong>片段缓存示例</strong>
<br />
<hr />
<uc1:ucc ID="Ucc1" runat="server" />
<br />
<hr />
<asp:Label ID="lblSelfTime" runat="server"></asp:Label>
</form>
</body>
</html>
<4>. 再新建一个.aspx文件,并删除页面文件中的HTML代码,把以下代码复制到页面文件中(注意顶部.cs文件引用别删除,有下划线的需要您替换)
<%@ Register Src="您的用户控件.ascx" TagName="ucc" TagPrefix="uc1" %>
<html >
<head id="Head1" runat="server">
<title>片段缓存示例2</title>
<script. type="text/C#" runat="server">
protected void Page_Load(object sender, EventArgs e)
{
this.lblSelfTime.Text = "self 2 time:" + DateTime.Now.ToString();
}
</script>
</head>
<body>
<form. id="form1" runat="server">
<strong>片段缓存示例2</strong>
<br />
<hr />
<uc1:ucc ID="Ucc1" runat="server" />
<br />
<hr />
<asp:Label ID="lblSelfTime" runat="server"></asp:Label>
</form>
</body>
</html>
<5>. 在浏览器中浏览您刚才新建的两个.aspx页面,会发现两个页面的用户控件的缓存是一样的(usercontrol time 是同时变化的),当您选择城市列表时,会发现用户控件为每一个城市都缓存了一个版本。不同页面的每个城市的缓存版本一样。
如果需要每个页面缓存版本不一样,就不要设置Shared="true"参数。大家可以通过上面的示例自己测试测试。
实战友情提示:
l 如果想每个页面引用的用户控件的缓存版本一样,就必须设置Shared="true"参数,并且用户控件ID一样
3、应用程序缓存
页面级和用户控件级缓存的确是一种可以迅速而简便地提高站点性能的方法,但是在ASP.NET中,缓存的真正灵活性和强大功能是通过Cache (System.Web.Caching.Cache)对象提供的。使用 Cache对象,您可以存储任何可序列化的数据对象,基于一个或多个依赖项的组合来控制缓存条目到期的方式。这些依赖项可以包括自从项被缓存后经过的时间、自从项上次被访问后经过的时间、对文件和/或文件夹的更改以及对其他缓存项的更改,在略作处理后还可以包括对数据库中特定表的更改。
实现
Cache对象位于System.Web.Caching. Cache中,其提供了两种增加缓存的方法,Add()和Insert()方法,这两种方法都有多个重载,且两种方法唯一的区别就是Add()返回已缓存对象的引用,Insert()没有返回值。Cache对象还提供了删除缓存的Remove()方法。
具体的缓存实践我这里提供了简易封装后一个缓存工具类。可以直接用于项目中(适用于ASP.NET 2.0项目)。
using System;
using System.Text;
using System.Web.Caching;
using System.Collections;
using System.Collections.Generic;
using System.Text.RegularExpressions;
namespace DianPing001.Cache
{
public static class ObjectCache
{
private static System.Web.Caching.Cache cache;
private static double _SaveTime;
/// <summary>
/// 缓存保存时间,以分钟计算,默认分钟
/// </summary>
public static double SaveTime
{
get { return _SaveTime; }
set { _SaveTime = value; }
}
static ObjectCache()
{
cache = System.Web.HttpContext.Current.Cache;
_SaveTime = 30.0;
}
/// <summary>
/// 获取缓存对象
/// </summary>
/// <param name="key">key</param>
/// <returns>object</returns>
public static object Get(string key)
{
return cache.Get(key);
}
/// <summary>
/// 获取缓存数据,需要传入类型
/// </summary>
public static T Get<T>(string key)
{
object bj = Get(key);
if (obj == null)
{
return default(T);
}
else
{
return (T)obj;
}
}
/// <summary>
/// 插入对象到缓存中
/// </summary>
/// <param name="key">key</param>
/// <param name="value">对象</param>
/// <param name="dependency">对象依赖</param>
/// <param name="priority">优先级</param>
/// <param name="callback">缓存删除时的回调事件</param>
public static void Insert(string key, object value, CacheDependency dependency, CacheItemPriority priority, CacheItemRemovedCallback callback)
{
cache.Insert(key, value, dependency, System.Web.Caching.Cache.NoAbsoluteExpiration, TimeSpan.FromMinutes(SaveTime), priority, callback);
}
/// <summary>
/// 插入对象到缓存中
/// </summary>
/// <param name="key">key</param>
/// <param name="value">对象</param>
/// <param name="dependency">对象依赖</param>
/// <param name="callback">缓存删除时的回调事件</param>
public static void Insert(string key, object value, CacheDependency dependency, CacheItemRemovedCallback callback)
{
Insert(key, value, dependency, CacheItemPriority.Default, callback);
}
/// <summary>
/// 插入对象到缓存中
/// </summary>
/// <param name="key">key</param>
/// <param name="value">对象</param>
/// <param name="dependency">对象依赖</param>
public static void Insert(string key, object value, CacheDependency dependency)
{
Insert(key, value, dependency, CacheItemPriority.Default, null);
}
/// <summary>
/// 插入对象到缓存中
/// </summary>
/// <param name="key">key</param>
/// <param name="value">对象</param>
public static void Insert(string key, object value)
{
Insert(key, value, null, CacheItemPriority.Default, null);
}
/// <summary>
/// 获取所有缓存对象的key
/// </summary>
/// <returns>返回一个IList对象</returns>
public static IList<string> GetKeys()
{
List<string> keys = new List<string>();
IDictionaryEnumerator cacheItem = cache.GetEnumerator();
while (cacheItem.MoveNext())
{
keys.Add(cacheItem.Key.ToString());
}
return keys.AsReadOnly();
}
/// <summary>
/// 删除缓存对象
/// </summary>
/// <param name="key">key</param>
public static void Remove(string key)
{
cache.Remove(key);
}
/// <summary>
/// 删除全部缓存
/// </summary>
public static void RemoveAll()
{
IList<string> keys = GetKeys();
foreach (string key in keys)
{
cache.Remove(key);
}
}
public static IList<string> RegexSearch(string pattern)
{
List<string> keys = new List<string>();
IDictionaryEnumerator cacheItem = cache.GetEnumerator();
while (cacheItem.MoveNext())
{
if (Regex.IsMatch(cacheItem.Key.ToString(), pattern))
{
keys.Add(cacheItem.Key.ToString());
}
}
return keys.AsReadOnly();
}
/// <summary>
/// 删除符合正则条件的cache
/// </summary>
/// <param name="pattern">条件</param>
public static void RegexRemove(string pattern)
{
IList<string> keys = RegexSearch(pattern);
foreach (string key in keys)
{
cache.Remove(key);
}
}
}
}
具体的使用场景
l 添加缓存
/// <summary>
/// 获取全部友情链接
/// </summary>
/// <returns></returns>
public List<Links> GetAll()
{
List<Links> linksList = ObjectCache.Get<List<Links>>("c_Links_ALL");[stone1]
if (linksList == null)
{
linksList = ProviderManager.Factory.Links.GetAll();
ObjectCache.Insert("c_Links_ALL",linksList);
}
[stone2]return linksList;
}
l 删除缓存
/// <summary>
/// 删除友情链接
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public int Delete(int id)
{
int retVar = ProviderManager.Factory.Links.Delete(id);
if (retVar > 0)
{
ObjectCache.RegexRemove("c_Links*");[stone3]
}
return retVar;
}
到这里,已经介绍了ASP.NET为我们提供的缓存方案,从简单的页面级和用户控件缓存,到功能强大、可灵活定制的Cache对象。这些已经基本满足我们日常的需求。当然,缓存的强大之处还需要我们在实战中慢慢体会。
4、分布式缓存
在ASP.NET中已经为我们提供了一些缓存方案,但是如果我们需要搭建分布式缓存系统的话,ASP.NET提供的方案就不够用了。因此我们需要其他的解决方案。寻觅的一段时间后,发现一个叫Memcached的用于分布式系统的缓存方案。如果你想快速搭建性能卓越,功能强大的分布式系统,那Memcached绝对是您不二的选择。
1)Memcached是什么?
memcached 是以LiveJournal 旗下Danga Interactive 公司的Brad Fitzpatric 为首开发的一款软件。许多Web应用都将数据保存到RDBMS中,应用服务器从中读取数据并在浏览器中显示。但随着数据量的增大、访问的集中,就会出现RDBMS的负担加重、数据库响应恶化、网站显示延迟等重大影响。
这时就该memcached大显身手了。memcached是高性能的分布式内存缓存服务器。一般的使用目的是,通过缓存数据库查询结果,减少数据库访问次数,以提高动态Web应用的速度、提高可扩展性。
2)Memcached能缓存什么?
通过在内存里维护一个统一的巨大的hash表,Memcached能够用来存储各种格式的数据,包括图像、视频、文件以及数据库检索的结果等。
3)Memcached快吗?
非常快,必须要介绍它的内部实现原理,只要知道有哪些站点在应用就可以了。Memcached已经成为mixi、hatena、Facebook、Vox、LiveJournal等众多服务中提高Web应用扩展性的重要因素。所以我们应该有理由相信Memcached的性能。
4)Memcached特点
memcached作为高速运行的分布式缓存服务器,具有以下的特点。
• 协议简单
• 基于libevent的事件处理
• 内置内存存储方式
• memcached不互相通信的分布式
5)Windows下Memcached的安装使用
a)安装Memcached Server
u 下载memcached的windows稳定版,解压放某个盘下面,比如在d:\memcached
u 在CMD下输入 "d:\memcached\memcached.exe -d install" 安装.
u 再输入:"d:\memcached\memcached.exe -d start" 启动。
备注:以后memcached将作为windows的一个服务每次开机时自动启动。这样服务器端已经安装完毕了。有几台缓存机器就为这些机器分别安装Memcached服务。
安装常用设置:
-p <num> 监听的端口
-l <ip_addr> 连接的IP地址, 默认是本机
-d start 启动memcached服务
-d restart 重起memcached服务
-d stop|shutdown 关闭正在运行的memcached服务
-d install 安装memcached服务
-d uninstall 卸载memcached服务
-u <username> 以<username>的身份运行 (仅在以root运行的时候有效)
-m <num> 最大内存使用,单位MB。默认64MB
-M 内存耗尽时返回错误,而不是删除项
-c <num> 最大同时连接数,默认是1024
-f <factor> 块大小增长因子,默认是1.25
-n <bytes> 最小分配空间,key+value+flags默认是48
-h 显示帮助
b)使用Memcached的.NET客户端
u 下载Memcached的.NET客户端(C#)
u 在项目中引用Enyim.Caching.dll文件
u 添加配置文件,WEB项目为web.config,客服端软件项目为App.config,配置代码为
<configuration>
<configSections>
<sectionGroup name="enyim.com">
<section name="memcached" type="Enyim.Caching.Configuration.MemcachedClientSection, Enyim.Caching" />
</sectionGroup>
<section name="memcached" type="Enyim.Caching.Configuration.MemcachedClientSection, Enyim.Caching" />
</configSections>
<enyim.com>
<memcached>
<servers>
<!-- put your own server(s) here-->
<add address="127.0.0.1" port="11211" />
<add address="192.168.111.189" port="11212" />
</servers>
<socketPool minPoolSize="10" maxPoolSize="100" connectionTimeout="00:00:10" deadTimeout="00:02:00" />
</memcached>
</enyim.com>
<memcached keyTransformer="Enyim.Caching.TigerHashTransformer, Enyim.Caching">
<servers>
<add address="127.0.0.1" port="11211" />
<add address="192.168.111.189" port="11212" />
</servers>
<socketPool minPoolSize="2" maxPoolSize="100" connectionTimeout="00:00:10" deadTimeout="00:02:00" />
</memcached>
</configuration>
u 测试代码
using System;
using System.Collections.Generic;
using System.Text;
using Enyim.Caching;
using Enyim.Caching.Memcached;
using Enyim.Caching.Configuration;
using System.Net;
namespace TestMemcached1
{
class Program
{
static void Main(string[] args)
{
string flag = "1"; //输入TAG,为插入缓存,为读取缓存数据,为删除缓存数据
string key = "";
string value = "";
MemcachedClient mc = new MemcachedClient();
Console.WriteLine("请输入操作类型(1插入缓存,读取缓存数据,删除缓存数据)...");
while((flag = Console.ReadLine().Trim()) != "")
{
switch (flag)
{
case "1": {
Console.WriteLine("请输入要插入缓存的KEY:");
key = Console.ReadLine().Trim();
Console.WriteLine("请输入与KEY对应的值:");
value = Console.ReadLine().Trim();
if (mc.Store(StoreMode.Set, key, value))
{
Console.WriteLine("{0}的值({1})插入成功",key,value);
}
}; break;
case "2": {
Console.WriteLine("请输入要删除的缓存的KEY");
key = Console.ReadLine().Trim();
if (mc.Get(key) == null)
{
Console.WriteLine("SORRY,{0}的值不存在", key);
}
else
{
if (mc.Remove(key))
{
Console.WriteLine("删除缓存({0})成功", key);
}
else
{
Console.WriteLine("删除缓存({0})失败", key);
}
}
}; break;
case "0": {
Console.WriteLine("请输入要读取缓存数据的KEY");
key = Console.ReadLine().Trim();
if (mc.Get(key) == null)
{
Console.WriteLine("SORRY,{0}的值不存在", key);
}
else
{
Console.WriteLine("{0}的缓存数据为{1}",key,mc.Get(key));
}
}; break;
default: Console.WriteLine("谢谢使用"); break;
}
}
}
}
}
c)运行结果
我是配置了两台服务器,本机和局域网内的一台机器,从配置文件中也可以看出具体配置了几台机器。
其运行结果也是非常让人满意的,我在本机添加的缓存,在192.168.111.189那台机器上面可以查询到刚刚添加的缓存,同样在189机器添加的缓存,我本机同样可以查询,当然删除也是同步的。
d)查看Memcached运行情况
使用telnet IP 端口 然后使用stats命令查看Memcached运行情况
e)实战友情提示:
Memcached在修改服务端口时发现CMD下的修改命令并不起效果。后来发现在安装好的Memcached服务的启动项中并没有端口设置(默认值为11211),于是想到进注册表修改其服务启动参数。打开注册表,按照路径HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\memcached Server,找到其中的ImagePath项,其值为:"d:\memcached\memcached.exe" -d runservice,将值修改为:"d:\memcached\memcached.exe" -p 80080 -m 256 -d runservice。重启服务后你就会发现该服务的端口已经变为80080了,-m 256表示设置了256M内存。
5、小结
到此为止,我们已经阐述了ASP.NET中各种缓存方案,并分享了一些实战经验。
从最基本的页面级和用户控件级简单缓存,到高灵活性、高性能的Cache缓存对象,以及功能强大、性能卓越的分布式缓存系统Memcached,我们都已经有所了解、有所深入。那么在实践过程中,我们应该根据自己的实际需要去选择具体的缓存方案。比如单服务器中,我们可以选择Cached缓存对象实现缓存,一些长期不做修改的动态页面我们可以选择页面级缓存,多页面公用的菜单我们可以选择用户控件缓存。分布式系统我们就可以选择Memcached解决方案。
有了这么多的缓存方案,让我们构建高性能的应用程序吧!
--------------------------------------------------------------------------------
[stone1]从缓存中读取数据并复制给对象列表
[stone2]如果未能从缓存中获取到数据,就先从数据库中读取,然后把对象添加到缓存中
[stone3]批量删除缓存(key中含有c_Links的缓存)
转载地址:http://space.itpub.net/183242/viewspace-700850
发表评论
-
过滤与缓存
2012-11-28 00:00 2272刚说要坚持写博客,这一晃两周过去了...汗啊, ... -
[转]Memcache and Mongodb
2012-11-26 16:26 1350原文链接: http://www.cnblog ... -
过滤与缓存
2012-11-27 23:57 2刚说要坚持写博客 ... -
缓存与分页
2012-11-07 02:14 6553最近再做服务端缓存性能的优化,上一篇《分布式缓存下缓存 ... -
缓存与分页
2012-11-07 02:04 4最近再做服务端缓存性能的优化,上一篇《分布式缓存下缓存 ... -
分布式缓存下缓存优化设计方案(一)
2012-10-26 01:31 11577相关知识:缓存cache、 ...
相关推荐
2. 处理输入的内存访问序列,每次访问时检查Cache命中情况。 3. 如果未命中,根据替换策略选择要替换的块,并从主存加载数据。 4. 更新Cache的状态信息,如有效位、修改位等。 5. 输出命中率等统计信息。 ### 5. ...
越来越多的现代处理器架构为程序员提供了透明的Cache处理机制,从而简化了开发工作。但在某些嵌入式平台上,由于技术发展的不均衡,程序员仍然需要手动处理这些问题。不过可以预见的是,随着技术的进步,对于大多数...
4. **构建Cache Control Logic**:使用Verilog的条件语句和计数器实现读/写状态机,处理各种情况,如命中、未命中、写回等。 5. **实现替换策略**:根据选择的替换策略,如LRU,实现相应的硬件逻辑。 6. **集成AXI...
通过这个映射关系,Cache数据库可以将用户的请求映射到对应的处理方法上,从而实现业务逻辑的处理。 二、创建Web服务 在Cache数据库中,我们可以创建Web服务来提供Restful接口。Web服务是Cache数据库提供的一种Web...
当系统中的某个设备或进程需要CPU立即响应时,它会发送一个中断信号给CPU,使得CPU暂停当前正在执行的任务,保存上下文,然后转去处理中断请求。处理完后,CPU再恢复之前的状态,继续执行原任务。中断对于实时性和多...
例如,伪相联Cache可能在处理复杂工作负载时展现出较高的命中率,而虚拟Cache则可能在减少访问延迟方面表现突出。“虚拟索引+物理标识”Cache则综合了两者的优点,提供了一种更为平衡的解决方案。 总之,通过深入...
总结来说,存储器系统由高速Cache、主存DRAM和慢速磁盘构成,它们各自承担不同的角色,共同确保计算机能高效地运行程序和处理数据。理解这些层次的特性和交互对于系统设计、性能优化和问题排查都具有重要意义。
CP15是ARM架构中的一种协处理器,用于配置和控制MMU、Cache等硬件特性。在ARM920T中,CP15主要用于控制MMU的设置,例如设置页表基址寄存器(Page Table Base Register, PTBR)等。 #### Cache工作原理 除了MMU之外...
- **MMU与Cache的初始化**:内核启动代码中包含了一系列用于初始化MMU和Cache的指令,这些指令确保了系统能够正确处理虚拟地址到物理地址的转换,同时优化了Cache的使用效率。 - **MMU与Cache的控制**:内核启动代码...
OpenCV(Open Source Computer Vision Library)是一个开源的计算机视觉库,包含了众多图像处理和计算机视觉的算法。在OpenCV 4.4版本中,开发者为了提高构建效率和方便性,引入了缓存机制,这就是“opencv4.4 build...
7. **写操作处理**:对于写操作,MIPS Cache支持写直达(立即写入主内存)和写回(延迟写入主内存,仅在替换时才写回)。写回策略可以减少对主内存的写操作,但可能导致一致性问题。 8. **伪命中(False Hit)和伪...
SuperCache.v5.0.524.0.ser.32bit.exe则是服务端组件,负责后台运行和数据处理。这两个组件的协同工作确保了缓存系统的稳定性和高效性。 此外,汉化补丁.exe文件为这款软件提供了中文界面,使得国内用户可以更方便...
设计者需要对Cache的工作原理有深入理解,包括其结构、组织方式、替换策略以及读写操作的处理。具体到TMS320C64x DSP,该处理器具有二级内存架构,包括L1P(一级程序Cache)和L1D(一级数据Cache),以及二级内存...
5. **设计读/写操作**:根据读写策略,编写控制逻辑来处理读取和写入请求。 6. **仿真和测试**:运行Logisim-Evolution,使用各种输入数据和主存访问模式进行测试,验证缓存行为的正确性。 在实现过程中,可能需要...
这可能涉及到文件格式转换、版权保护处理以及用户界面设计等方面的知识,对于音乐分享应用的开发提供了实践指导。 总的来说,“BaiduMusic Cache源码20130823”不仅是一份代码资源,更是一本生动的教科书,涵盖了...
Cache,即高速缓存存储器,是一种位于中央处理器(CPU)与主存储器(DRAM)之间的小型高速存储器,通常由静态随机存取存储器(SRAM)构成。SRAM采用与CPU相同的制造工艺,因此具有较高的读写速度。由于动态RAM(DRAM...
【基于SystemC的Cache一致性协议描述与验证】 在多处理器系统设计中,Cache一致性协议扮演着至关重要的角色,它确保了各个处理器访问共享主存时数据的一致性。随着微电子技术的发展,SystemC作为一种系统级设计语言...
**ESB(Enterprise Service Bus,企业服务总线)与Cache详解** **一、ESB概念与作用** ESB是企业级应用集成中的一个重要组件,它作为一个中间件平台,旨在简化和标准化不同系统间的通信。ESB的核心功能包括消息传递...
在ARM920T处理器中,CP15协处理器负责管理MMU和Cache的操作。通过特定的指令,操作系统可以在启动时配置和控制这些功能。例如,设置页表以建立虚拟地址到物理地址的映射,以及初始化和管理Cache,包括清除、填充和...